Created
May 24, 2019 04:37
-
-
Save IanSSenne/88d0e2fa2f8f991ba79d4aa5d72c3509 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I should note that the naming is based on my understandings of the concept be it correct or not