export const enum WalkAction {
Continue,
Skip,
Stop,
}
interface Walkable<T> {
each(cb: (node: T, index: number) => void): void
}
export function walk<T>(
rule: Walkable<T>,
cb: (rule: T, idx: number, parent: Walkable<T>) => void | WalkAction,
): undefined | false {
let result: undefined | false = undefined
rule.each?.((node, idx) => {
let action = cb(node, idx, rule) ?? WalkAction.Continue
if (action === WalkAction.Stop) {
result = false
return result
}
if (action !== WalkAction.Skip) {
result = walk(node as Walkable<T>, cb)
return result
}
})
return result
}
export function walkDepth<T>(rule: Walkable<T>, cb: (rule: T) => void) {
rule?.each?.((node) => {
walkDepth(node as Walkable<T>, cb)
cb(node)
})
}