Just musing:
interface Pattern<T> {
(matcher: (string | Macro | Pattern<unknown>)[]): Pattern<T>;
resolve<S>(callback: (parsed: string[]) => S): Pattern<S>;
convert(descriptor): Pattern<T>;
fromString(string: string): Parsable<T>;
}
interface Parsable<T> {
parse: () => Promise<T>;
}
interface Macro {
(...args): Pattern<unknown>;
}
const pattern = {} as Pattern<unknown>;
const string = {} as Macro;
const number = {} as Macro;
const repeat = {} as Macro;
const or = {} as Macro;
const option = {} as Macro;
const types = {
number: pattern(['number']).resolve(() => 'number'),
date: pattern(['date']).resolve(() => 'date'),
};
const type = pattern([or(types.number, types.date)]);
const cell = pattern([
string({ case: 'upper', characters: 'alphabetic' }),
number({ range: { start: 1 } }),
]).resolve(([column, row]) => [row, column]);
const range = pattern([cell, cell]).resolve(([start, end]) => ({ start, end }));
const selection = pattern([repeat(cell, range, { seperator: ',' })]).convert({
cell: value => ({ start: value, end: value }),
});
const format = pattern(['format', selection, 'as', type]);
const command = format.fromString('format A1:A10,B1 as date');
command.parse().then(([selection, type]) => {
console.log(selection, type);
});
Just musing: