1
0

Filter implementation started

This commit is contained in:
Bán Dénes 2021-12-26 14:06:30 +01:00
parent e48631fac8
commit 534ac4b75d

86
src/filter.js Normal file
View File

@ -0,0 +1,86 @@
const u = require('./utils')
const a = require('./assert')
const anchor = require('./anchor').parse
const _true = () => true
const _and = arr => p => arr.map(e => e(p)).reduce((a, b) => a && b)
const _or = arr => p => arr.map(e => e(p)).reduce((a, b) => a || b)
const similar = (a, b, name, units) => {
let neg = false
if (b.startsWith('-')) {
neg = true
b = b.slice(1)
}
if (b.startsWith('/')) {
//...
}
}
const comparators = {
'~': similar
// TODO: extension point for other operators...
}
const symbols = Object.keys(comparators)
const simple = (exp, name, units) => {
let a = ['meta.name', 'meta.tags']
let op = '~'
let b
const parts = exp.split(/\s+/g)
// full case
if (symbols.includes(parts[1])) {
a = parts[0].split(',')
op = parts[1]
b = parts.slice(2).join(' ')
// middle case, just an operator spec, default "a"
} else if (symbols.includes(parts[0])) {
op = parts[0]
b = parts.slice(1).join(' ')
// basic case, only "b"
} else {
b = exp
}
return comparators[op](a, b, name, units)
}
const complex = (config, name, units, aggregator=_and) => {
// default is all points
if (config === undefined) {
return _true
}
// otherwise we branch by type
const type = a.type(config)()
switch(type) {
// base case is a string, meaning a simple/single filter
case 'string':
return simple(config, name, units)
// arrays are aggregated with alternating and/or conditions
case 'array':
const alternate = aggregator == _and ? _or : _and
return aggregator(config.map(elem => complex(elem, name, units, alternate)))
default:
throw new Error(`Unexpected type "${type}" found at filter "${name}"!`)
}
}
exports.parse = (config, name, points={}, units={}) => {
if (a.type(config)() == 'object') {
return [anchor(config, name, points)(units)]
}
return Object.values(points).filter(complex(config, name, units))
}