From faffb83d1d209f8d9e0e27e9f023612f2865dd4e Mon Sep 17 00:00:00 2001 From: Michael Lange Date: Mon, 11 Nov 2019 17:18:41 -0800 Subject: [PATCH] Extract the duration parsing into a util --- ui/app/components/drain-popover.js | 80 +----------------------------- ui/app/utils/parse-duration.js | 75 ++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 78 deletions(-) create mode 100644 ui/app/utils/parse-duration.js diff --git a/ui/app/components/drain-popover.js b/ui/app/components/drain-popover.js index 9ecccb3a4..1770e54f4 100644 --- a/ui/app/components/drain-popover.js +++ b/ui/app/components/drain-popover.js @@ -3,83 +3,7 @@ import { computed } from '@ember/object'; import { equal } from '@ember/object/computed'; import { computed as overridable } from 'ember-overridable-computed'; import { task } from 'ember-concurrency'; - -const durationDecode = str => { - const durationUnits = ['d', 'h', 'm', 's']; - const unitToMs = { - s: 1000, - m: 1000 * 60, - h: 1000 * 60 * 60, - d: 1000 * 60 * 60 * 24, - }; - - if (typeof str === 'number') return str; - - // Split the string into characters to make iteration easier - const chars = str.split(''); - - // Collect tokens - const tokens = []; - - // A token can be multi-character, so collect characters - let token = []; - - // If a non-numeric character follows a non-numeric character, that's a - // parse error, so this marker bool is needed - let disallowChar = false; - - // Take the first character off the chars array until there are no more - while (chars.length) { - let next = chars.shift(); - - // Check to see if the char is numeric - if (next >= 0 && next < 10) { - // Collect numeric characters until a non-numeric shows up - token.push(next); - // Release the double non-numeric mark - disallowChar = false; - } else { - if (disallowChar) { - throw new Error( - `ParseError: [${str}] Cannot follow a non-numeric token with a non-numeric token` - ); - } - if (!durationUnits.includes(next)) { - throw new Error(`ParseError: [${str}] Unallowed duration unit "${next}"`); - } - - // The token array now becomes a single int token - tokens.push(parseInt(token.join(''))); - // This non-numeric char is its own token - tokens.push(next); - - // Reset token array - token = []; - // Set the double non-numeric mark - disallowChar = true; - } - } - - // If there are numeric characters still in the token array, then there must have - // not been a followup non-numeric character which would have flushed the numeric tokens. - if (token.length) { - throw new Error(`ParseError: [${str}] Unmatched quantities and units`); - } - - // Loop over the tokens array, two at a time, converting unit and quanties into milliseconds - let duration = 0; - while (tokens.length) { - const quantity = tokens.shift(); - const unit = tokens.shift(); - duration += quantity * unitToMs[unit]; - } - - // Convert from Milliseconds to Nanoseconds - duration *= 1000000; - - console.log('DURATION', duration); - return duration; -}; +import parseDuration from 'nomad-ui/utils/parse-duration'; export default Component.extend({ tagName: '', @@ -128,7 +52,7 @@ export default Component.extend({ let deadline; try { - deadline = durationDecode(this.deadline); + deadline = parseDuration(this.deadline); } catch (err) { this.set('parseError', err.message); return; diff --git a/ui/app/utils/parse-duration.js b/ui/app/utils/parse-duration.js new file mode 100644 index 000000000..8e7e2b29c --- /dev/null +++ b/ui/app/utils/parse-duration.js @@ -0,0 +1,75 @@ +export default str => { + const durationUnits = ['d', 'h', 'm', 's']; + const unitToMs = { + s: 1000, + m: 1000 * 60, + h: 1000 * 60 * 60, + d: 1000 * 60 * 60 * 24, + }; + + if (typeof str === 'number') return str; + + // Split the string into characters to make iteration easier + const chars = str.split(''); + + // Collect tokens + const tokens = []; + + // A token can be multi-character, so collect characters + let token = []; + + // If a non-numeric character follows a non-numeric character, that's a + // parse error, so this marker bool is needed + let disallowChar = false; + + // Take the first character off the chars array until there are no more + while (chars.length) { + let next = chars.shift(); + + // Check to see if the char is numeric + if (next >= 0 && next < 10) { + // Collect numeric characters until a non-numeric shows up + token.push(next); + // Release the double non-numeric mark + disallowChar = false; + } else { + if (disallowChar) { + throw new Error( + `ParseError: [${str}] Cannot follow a non-numeric token with a non-numeric token` + ); + } + if (!durationUnits.includes(next)) { + throw new Error(`ParseError: [${str}] Unallowed duration unit "${next}"`); + } + + // The token array now becomes a single int token + tokens.push(parseInt(token.join(''))); + // This non-numeric char is its own token + tokens.push(next); + + // Reset token array + token = []; + // Set the double non-numeric mark + disallowChar = true; + } + } + + // If there are numeric characters still in the token array, then there must have + // not been a followup non-numeric character which would have flushed the numeric tokens. + if (token.length) { + throw new Error(`ParseError: [${str}] Unmatched quantities and units`); + } + + // Loop over the tokens array, two at a time, converting unit and quanties into milliseconds + let duration = 0; + while (tokens.length) { + const quantity = tokens.shift(); + const unit = tokens.shift(); + duration += quantity * unitToMs[unit]; + } + + // Convert from Milliseconds to Nanoseconds + duration *= 1000000; + + return duration; +};