Last active
October 29, 2018 12:10
-
-
Save StarpTech/3b009eec086a800f1575c129d08e7f02 to your computer and use it in GitHub Desktop.
Small library to validate numeric data structures in a functional-style
This file contains hidden or 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
/** | |
* Small library to validate numeric data structures in a functional-style | |
* All functions are right associative | |
* If you are looking for more sophisticated features have a look at | |
* https://ramdajs.com/ | |
*/ | |
export interface FabPattern { | |
[index: string]: (input: number) => boolean; | |
} | |
export class Fab { | |
static gt(...mem: number[]) { | |
return (input: number) => mem.every(m => input > m); | |
} | |
static lt(...mem: number[]) { | |
return (input: number) => mem.every(m => input < m); | |
} | |
static lte(...mem: number[]) { | |
return (input: number) => mem.every(m => input <= m); | |
} | |
static gte(...mem: number[]) { | |
return (input: number) => mem.every(m => input >= m); | |
} | |
static equals(...mem: number[]) { | |
return (input: number) => mem.every(m => input === m); | |
} | |
static and(...mem: Function[]) { | |
return (input: number) => mem.every(m => m(input)); | |
} | |
static either(...mem: Function[]) { | |
return (input: number) => mem.findIndex(m => m(input)) > -1; | |
} | |
/** | |
* Validate the pattern and returns the result | |
* @param pattern | |
*/ | |
static where(pattern: FabPattern) { | |
return (obj: {[key: string]: any}) => { | |
for (const key in pattern) { | |
const check = pattern[key]; | |
const input = obj[key]; | |
if (key in obj && typeof check === 'function') { | |
if (check(input) === false) return false; | |
} | |
} | |
return true; | |
}; | |
} | |
/** | |
* Validate the pattern and resolve with a value or default value | |
* @param pattern | |
* @param value | |
* @param defaultValue | |
*/ | |
static cond(pattern: FabPattern, value: any, defaultValue?: any) { | |
return (obj: {[key: string]: any}) => { | |
if (Fab.where(pattern)(obj)) { | |
return value; | |
} | |
return defaultValue; | |
}; | |
} | |
/** | |
* Validates an array of "cond" and returns the first match | |
* @param mem | |
*/ | |
static anyCond(...mem: Function[]) { | |
return (obj: {[key: string]: any}) => { | |
for (const m of mem) { | |
const result = m(obj); | |
if (result) { | |
return result; | |
} | |
} | |
}; | |
} | |
} | |
const validate = Fab.where({ | |
a: Fab.and( | |
Fab.gt(100), | |
Fab.lte(300), | |
Fab.either(Fab.equals(200), Fab.equals(220)) | |
), | |
b: Fab.equals(0.15), | |
c: Fab.either(Fab.equals(0), Fab.equals(2), Fab.equals(3)) | |
}); | |
console.log(validate({ a: 220, b: 0.15, c: 3 })); | |
console.log(validate({ a: 199, b: 0 })); | |
const validate2 = Fab.cond( | |
{ | |
a: Fab.and(Fab.gt(100), Fab.lte(300)) | |
}, | |
"foo" | |
); | |
console.log(validate2({ a: 200 })); | |
const validate3 = Fab.anyCond( | |
Fab.cond( | |
{ | |
a: Fab.and(Fab.gt(100), Fab.lte(300)) | |
}, | |
"foo" | |
), | |
Fab.cond( | |
{ | |
a: Fab.and(Fab.gt(500), Fab.lte(800)) | |
}, | |
"bar" | |
) | |
); | |
console.log(validate3({ a: 200 })); | |
console.log(validate3({ a: 600 })); | |
console.log(validate3({ a: 900 })); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment