Skip to content

Commit

Permalink
Add optimized version for review
Browse files Browse the repository at this point in the history
  • Loading branch information
thecrypticace committed Dec 15, 2021
1 parent b7fd473 commit 202e710
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/util/toPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,95 @@
export function toPath(path) {
if (Array.isArray(path)) return path

let parts = []
let inBrackets = false
let partStart = 0
let partEnd = 0

for (let i = 0, len = path.length; i <= len; i++) {
let prev = path[i - 1]
let curr = path[i]

// Tokens:
// [ = lb
// ] = rb
// . = dot if not in brackets
// . = ident if in brackets
// everything else = ident
let prevIsIdent = inBrackets
? prev !== undefined && prev !== '[' && prev !== ']'
: prev !== undefined && prev !== '.' && prev !== '[' && prev !== ']'

let currIsIdent = inBrackets
? curr !== undefined && curr !== '[' && curr !== ']'
: curr !== undefined && curr !== '.' && curr !== '[' && curr !== ']'

// The only valid transitions are:
// start -> dot | lb | ident | end
// dot -> ident
// lb -> rb | ident
// rb -> dot | lb
// ident -> dot | rb | ident | end
// ident -> lb if not in brackets
if (
(prev === undefined && curr === ']') ||
(prev === '.' && !inBrackets && !currIsIdent) ||
(prev === '[' && curr === undefined) ||
(prev === '[' && curr === '[') ||
(prev === ']' && curr === ']') ||
(prev === ']' && currIsIdent) ||
(prevIsIdent && curr === '[' && inBrackets)
) {
throw new Error(`Invalid path: ${path}\n` + `${' '.repeat(14 + i)}^`)
}

// The last thing we looked at was an ident so we ened to keep looking for more
// Later scans will identify the end of the ident
if (prevIsIdent) {
partEnd = i
}

// Whenever we go from an ident to a non-ident we capture the new part
// We also capture:
// - start -> dot for initial empty strings
// - lb -> rb for ocurrences of [] also treated as empty strings
if (
(prev === undefined && curr === '.') ||
(prev === '[' && curr === ']') ||
(prevIsIdent && curr === '.' && !inBrackets) ||
(prevIsIdent && curr === '[' && !inBrackets) ||
(prevIsIdent && curr === ']') ||
(prevIsIdent && curr === undefined)
) {
parts.push(path.slice(partStart, partEnd))
}

// Whenever we go from a non-ident to ident we start capturing a new part
// We also capture start -> lb for initial empty strings generated by `[]`
if (
(prev === undefined && curr === '[') ||
(prev === '.' && !inBrackets && currIsIdent) ||
(prev === '[' && currIsIdent) ||
(prev === ']' && curr === '.')
) {
partStart = partEnd = i
}

// Bracket bookkeeping
if (curr === '[') {
inBrackets = true
} else if (curr === ']') {
inBrackets = false
}
}

return parts
}

// Herre for reference in case one is preferred over the other
export function toPathFull(path) {
if (Array.isArray(path)) return path

// The general outline/properties of a path string:

// Tokens:
Expand Down

0 comments on commit 202e710

Please sign in to comment.