Skip to content

Instantly share code, notes, and snippets.

@IanSSenne
Created May 24, 2019 04:37
Show Gist options
  • Save IanSSenne/88d0e2fa2f8f991ba79d4aa5d72c3509 to your computer and use it in GitHub Desktop.
Save IanSSenne/88d0e2fa2f8f991ba79d4aa5d72c3509 to your computer and use it in GitHub Desktop.
const test = struct {
a: String or Number,
b: Number,
c: (Number or String) or Error
}
const user = struct {
email: String,
password: String,
username: String
}
user.validate({
email: "[email protected]",
password: "12345",
username: "hello world"
});
test.validate({
a: "test",
b: Infinity,
c: new Error()
});
function try_throw() {
return false;
}
class struct_array {
constructor(type_13) {
this.items = type_13;
}
validate(arr_14) {
for (let i = 0; i < arr_14.length; i++) {
if (this.items.constructor === struct_or || this.items.constructor === struct_struct) {
this.items.validate(arr_14[i]);
} else {
if (arr_14[i].constructor != this.items) return try_throw(new Error("failed to validate, type mismatch"));
}
}
return true;
}
}
class struct_or {
constructor(...args_15) {
this.items = args_15;
}
validate(obj_16) {
let is_ok_17 = false;
for (let i = 0; i < this.items.length; i++) {
if (this.items[i] === obj_16.constructor) is_ok_17 = true;
}
if (!is_ok_17) return try_throw(new Error("failed to validate, type mismatch"));
return true;
}
}
class struct_struct {
constructor(object_18) {
for (let key of Object.keys(object_18)) {
let res_19 = object_18[key];
if (res_19.constructor === Object) {
this[key] = new struct_struct(res_19);
} else {
this[key] = res_19;
}
}
}
validate(object_20) {
let keys_a_21 = Object.keys(object_20);
let keys_self_22 = Object.keys(this);
if (keys_a_21.length != keys_self_22.length) return try_throw(new Error("failed to validate, has missing or extra keys"));
for (let i = 0; i < keys_self_22.length; i++) {
if (!keys_a_21.includes(keys_self_22[i])) return try_throw(new Error("failed to validate, keys mismatch"));
}
for (let i = 0; i < keys_self_22.length; i++) {
if (this[keys_self_22[i]].constructor === struct_struct || this[keys_self_22[i]].constructor === struct_or || this[keys_self_22[i]].constructor === struct_array) {
this[keys_self_22[i]].validate(object_20[keys_self_22[i]]);
} else {
if (this[keys_self_22[i]] != object_20[keys_self_22[i]].constructor) {
return try_throw(new Error("failed to validate, type mismatch"));
}
}
}
}
}
const test_11 = new struct_struct({ a: new struct_or(String, Number), b: Number, c: new struct_or(new struct_or(Number, String), Error) });
const user_12 = new struct_struct({ email: String, password: String, username: String });
user_12.validate({ email: "[email protected]", password: "12345", username: "hello world" });
test_11.validate({ a: "test", b: Infinity, c: new Error() });
syntax struct = function (ctx) {
let structure = ctx.next().value;
return #`new struct_struct(${structure})`;
}
syntax array = function(ctx){
return #`new struct_array(${ctx.next().value})`;
}
operator or left 1 = (left,right)=>{
return #`new struct_or(${left},${right})`;
}
function try_throw(){
return false;
}
class struct_array{
constructor(type){
this.items=type;
}
validate(arr){
for(let i = 0;i<arr.length;i++){
if(this.items.constructor===struct_or||this.items.constructor===struct_struct){
this.items.validate(arr[i]);
}else{
if(arr[i].constructor!=this.items)return try_throw(new Error("failed to validate, type mismatch"));
}
}
return true;
}
}
class struct_or{
constructor(...args){
this.items=args;
}
validate(obj){
let is_ok = false;
for(let i = 0;i<this.items.length;i++){
if(this.items[i]===obj.constructor)is_ok=true;
}
if(!is_ok)return try_throw(new Error("failed to validate, type mismatch"));
return true;
}
}
class struct_struct{
constructor(object){
for(let key of Object.keys(object)){
let res = object[key];
if(res.constructor===Object){
this[key]=new struct_struct(res);
}else{
this[key]=res;
}
}
}
validate(object) {
let keys_a = Object.keys(object);
let keys_self = Object.keys(this);
if(keys_a.length!=keys_self.length)return try_throw(new Error("failed to validate, has missing or extra keys"));
for(let i = 0;i<keys_self.length;i++){
if(!keys_a.includes(keys_self[i]))return try_throw(new Error("failed to validate, keys mismatch"));
}
for(let i = 0;i<keys_self.length;i++){
if(this[keys_self[i]].constructor===struct_struct || this[keys_self[i]].constructor===struct_or || this[keys_self[i]].constructor===struct_array){
this[keys_self[i]].validate(object[keys_self[i]]);
}else{
if(this[keys_self[i]]!=object[keys_self[i]].constructor){
return try_throw(new Error("failed to validate, type mismatch"));
}
}
}
}
}
@IanSSenne
Copy link
Author

I should note that the naming is based on my understandings of the concept be it correct or not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment