Skip to content

Instantly share code, notes, and snippets.

@saikyun
Last active April 19, 2024 11:36
Show Gist options
  • Save saikyun/965eb142f9add73ce0c7f936cf9ddff3 to your computer and use it in GitHub Desktop.
Save saikyun/965eb142f9add73ce0c7f936cf9ddff3 to your computer and use it in GitHub Desktop.
export class AssertionError extends Error {
constructor(message) {
super(message)
this.name = "AssertionError"
}
}
export const assert = (pred, msg = "") => {
if (typeof pred === "function") {
if (pred()) return true
else throw new AssertionError(msg + pred.toString())
} else {
if (pred) return true
else throw new AssertionError(msg)
}
}
// assert(() => 1 === 3)
const to_string = (o) =>
typeof o === "object" || Array.isArray(o) ? JSON.stringify(o) : o.toString()
export const pre = (...stuff) => {
const f = stuff[stuff.length - 1]
const preds = stuff.slice(0, stuff.length - 1)
return (...args) => {
for (const [i, p] of preds.entries()) {
assert(Array.isArray(p) || typeof p === "function")
console.log(p)
if (
(Array.isArray(p) && !p[0](args[i], ...p.slice(1))) ||
(typeof p === "function" && !p(args[i]))
)
throw new AssertionError(
`argument ${i} with value ${to_string(
args[i]
)} doesn't fulfill: ${p.toString()}`
)
}
return f(...args)
}
}
export const has_keys = (o, ...keys) => {
for (const k of keys)
if (o[k] == null)
throw new AssertionError(
`${to_string(o)} does not have key ${to_string(k)}`
)
return true
}
export const isa = (o, kind) => {
for (const k of Object.keys(kind)) {
if (!kind[k](o[k]))
throw new AssertionError(
`
key
${k}
in
${to_string(o)}
doesn't fulfill
${kind[k]}`
)
}
return true
}
/** Takes a starting value and zero or more functions
* those functions are called in order on the value.
* If the value or the return value of a function is ever
* `null`, `undefined` or `instanceof Error`,
* then that "failed" value is returned.
* Otherwise, the result of the last function is returned.
*
* Handles promises as well.
*/
export const chain = (value, ...fs) => {
var v = value
var i = 0
const [f, ...rest] = fs
if (!f || v == null || v instanceof Error) {
return v
}
if (v instanceof Promise) {
return v.then((v) => chain(v, ...fs)).catch((e) => e)
} else {
try {
return chain(f(v), ...rest)
} catch (e) {
return e
}
}
}
export const get = (o, el) => (o == null ? null : o[el])
export const first = (o) => get(o, 0)
export const last = (l) => (l == null ? null : get(l, l.length - 1))
export const len = (l) => (l == null ? null : l.length)
import { last } from "./fun.js"
export const log = (...exprs) => {
console.log(...exprs)
return last(exprs)
}
{
"name": "utiljs",
"type": "module",
"main": "util.js"
}
export { log } from "./log.js"
export { chain, get, first, last, len } from "./fun.js"
export { AssertionError, assert, has_keys, isa, pre } from "./assert.js"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment