Parsing of parameters

This commit is contained in:
Rene Saarsoo 2020-09-17 23:40:40 +03:00
parent 1779369e36
commit 29f12552ec
1 changed files with 89 additions and 8 deletions

View File

@ -1,18 +1,94 @@
import * as fs from "fs"; import * as fs from "fs";
type Def = { enum RuleType {
type: string; Name = "Name",
text: string; Author = "Author",
Description = "Description",
Warmup = "Warmup",
Rest = "Rest",
Interval = "Interval",
Cooldown = "Cooldown",
}
type Rule = {
type: RuleType;
params: Param[];
}; };
const parseDefinition = (line: string): Def | undefined => { enum ParamType {
Text = "Text",
Power = "Power",
PowerRange = "PowerRange",
Cadence = "Cadence",
Duration = "Duration",
}
type TextParam = { type: ParamType.Text; value: string };
type PowerParam = { type: ParamType.Power; value: number };
type PowerRangeParam = { type: ParamType.PowerRange; value: [number, number] };
type CadenceParam = { type: ParamType.Cadence; value: number };
type DurationParam = { type: ParamType.Duration; value: number };
type Param =
| TextParam
| PowerParam
| PowerRangeParam
| CadenceParam
| DurationParam;
const toInteger = (str: string): number => {
return parseInt(str.replace(/[^0-9]/, ""), 10);
};
const toSeconds = (str: string): number => {
const [seconds, minutes, hours] = str.split(":").map(toInteger).reverse();
return seconds + minutes * 60 + (hours || 0) * 60 * 60;
};
const parseValueParam = (text: string): Param => {
if (/^[0-9:]+$/.test(text)) {
return { type: ParamType.Duration, value: toSeconds(text) };
}
if (/^[0-9]+rpm$/.test(text)) {
return { type: ParamType.Cadence, value: toInteger(text) };
}
if (/^[0-9]+%..[0-9]+%$/.test(text)) {
const [from, to] = text.split("..").map(toInteger);
return { type: ParamType.PowerRange, value: [from, to] };
}
if (/^[0-9]+%$/.test(text)) {
return { type: ParamType.Power, value: toInteger(text) };
}
throw new Error(`Unrecognized parameter "${text}"`);
};
const parseParams = (type: RuleType, text: string): Param[] => {
switch (type) {
case RuleType.Name:
case RuleType.Author:
case RuleType.Description:
return [{ type: ParamType.Text, value: text }];
case RuleType.Warmup:
case RuleType.Rest:
case RuleType.Interval:
case RuleType.Cooldown:
return text.split(" ").map(parseValueParam);
}
};
const parseRule = (line: string): Rule | undefined => {
const matches = line.match(/^(\w+):(.*)$/); const matches = line.match(/^(\w+):(.*)$/);
if (!matches) { if (!matches) {
return undefined; return undefined;
} }
if (!Object.keys(RuleType).includes(matches[1])) {
return undefined;
}
const type: RuleType = matches[1] as RuleType;
return { return {
type: matches[1], type,
text: matches[2], params: parseParams(type, matches[2].trim()),
}; };
}; };
@ -26,6 +102,11 @@ const file = fs.readFileSync(filename, "utf8");
file file
.split(/\n/) .split(/\n/)
.map(parseDefinition) .map(parseRule)
.filter(isDefined) .filter(isDefined)
.forEach((def) => console.log(def.type)); .forEach((rule) => {
console.log(rule.type);
rule.params.forEach((p) => {
console.log(` ${p.type}: ${p.value}`);
});
});