From 29f12552ec3d2538def957b617272ae3e247cb9b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 17 Sep 2020 23:40:40 +0300 Subject: [PATCH] Parsing of parameters --- src/index.ts | 97 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index b90cabf..9de4c9c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,94 @@ import * as fs from "fs"; -type Def = { - type: string; - text: string; +enum RuleType { + Name = "Name", + 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+):(.*)$/); if (!matches) { return undefined; } + if (!Object.keys(RuleType).includes(matches[1])) { + return undefined; + } + const type: RuleType = matches[1] as RuleType; + return { - type: matches[1], - text: matches[2], + type, + params: parseParams(type, matches[2].trim()), }; }; @@ -26,6 +102,11 @@ const file = fs.readFileSync(filename, "utf8"); file .split(/\n/) - .map(parseDefinition) + .map(parseRule) .filter(isDefined) - .forEach((def) => console.log(def.type)); + .forEach((rule) => { + console.log(rule.type); + rule.params.forEach((p) => { + console.log(` ${p.type}: ${p.value}`); + }); + });