ergogen/src/assert.js
2022-12-03 17:40:01 +01:00

80 lines
2.8 KiB
JavaScript

const m = require('makerjs')
const u = require('./utils')
const Point = require('./point')
const mathjs = require('mathjs')
const mathnum = exports.mathnum = raw => units => {
return mathjs.evaluate(`${raw}`, units || {})
}
const assert = exports.assert = (exp, msg) => {
if (!exp) {
throw new Error(msg)
}
}
const type = exports.type = val => units => {
if (Array.isArray(val)) return 'array'
if (val === null) return 'null'
try {
const num = mathnum(val)(units)
if (typeof num === 'number') return 'number'
} catch (err) {}
return typeof val
}
const sane = exports.sane = (val, name, _type) => units => {
assert(type(val)(units) == _type, `Field "${name}" should be of type ${_type}!`)
if (_type == 'number') return mathnum(val)(units)
return val
}
const unexpected = exports.unexpected = (obj, name, expected) => {
const sane_obj = sane(obj, name, 'object')()
for (const key of Object.keys(sane_obj)) {
assert(expected.includes(key), `Unexpected key "${key}" within field "${name}"!`)
}
}
const _in = exports.in = (raw, name, arr) => {
assert(arr.includes(raw), `Field "${name}" should be one of [${arr.join(', ')}]!`)
return raw
}
const arr = exports.arr = (raw, name, length, _type, _default) => units => {
assert(type(raw)(units) == 'array', `Field "${name}" should be an array!`)
assert(length == 0 || raw.length == length, `Field "${name}" should be an array of length ${length}!`)
raw = raw.map(val => val === undefined ? _default : val)
raw.map(val => assert(type(val)(units) == _type, `Field "${name}" should contain ${_type}s!`))
if (_type == 'number') {
raw = raw.map(val => mathnum(val)(units))
}
return raw
}
const numarr = exports.numarr = (raw, name, length) => units => arr(raw, name, length, 'number', 0)(units)
const strarr = exports.strarr = (raw, name) => arr(raw, name, 0, 'string', '')()
const xy = exports.xy = (raw, name) => units => numarr(raw, name, 2)(units)
const wh = exports.wh = (raw, name) => units => {
if (!Array.isArray(raw)) raw = [raw, raw]
return xy(raw, name)(units)
}
exports.trbl = (raw, name, _default=0) => units => {
if (!Array.isArray(raw)) raw = [raw, raw, raw, raw]
if (raw.length == 2) raw = [raw[1], raw[0], raw[1], raw[0]]
return arr(raw, name, 4, 'number', _default)(units)
}
exports.asym = (raw, name) => {
// allow different aliases
const source_aliases = ['source', 'origin', 'base', 'primary', 'left']
const clone_aliases = ['clone', 'image', 'derived', 'secondary', 'right']
_in(raw, name, ['both'].concat(source_aliases, clone_aliases))
// return aliases to canonical names
if (source_aliases.includes(raw)) return 'source'
if (clone_aliases.includes(raw)) return 'clone'
return raw
}