50 lines
1.3 KiB
JavaScript
50 lines
1.3 KiB
JavaScript
export const parse = (stream, schema, result = {}, parent = result) => {
|
|
if (Array.isArray(schema)) {
|
|
schema.forEach(partSchema => parse(stream, partSchema, result, parent))
|
|
} else if (typeof schema === 'function') {
|
|
schema(stream, result, parent, parse)
|
|
} else {
|
|
const key = Object.keys(schema)[0]
|
|
if (Array.isArray(schema[key])) {
|
|
parent[key] = {}
|
|
parse(stream, schema[key], result, parent[key])
|
|
} else {
|
|
parent[key] = schema[key](stream, result, parent, parse)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
export const conditional = (schema, conditionFunc) => (
|
|
stream,
|
|
result,
|
|
parent,
|
|
parse
|
|
) => {
|
|
if (conditionFunc(stream, result, parent)) {
|
|
parse(stream, schema, result, parent)
|
|
}
|
|
}
|
|
|
|
export const loop = (schema, continueFunc) => (
|
|
stream,
|
|
result,
|
|
parent,
|
|
parse
|
|
) => {
|
|
const arr = []
|
|
let lastStreamPos = stream.pos;
|
|
while (continueFunc(stream, result, parent)) {
|
|
const newParent = {}
|
|
parse(stream, schema, result, newParent)
|
|
// cases when whole file is parsed but no termination is there and stream position is not getting updated as well
|
|
// it falls into infinite recursion, null check to avoid the same
|
|
if(stream.pos === lastStreamPos) {
|
|
break
|
|
}
|
|
lastStreamPos = stream.pos
|
|
arr.push(newParent)
|
|
}
|
|
return arr
|
|
}
|