-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ Parse list notation #159
Conversation
Codecov Report
@@ Coverage Diff @@
## master #159 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 79 79
Lines 296 306 +10
=====================================
+ Hits 296 306 +10
Continue to review full report at Codecov.
|
I deliberatly changed the behavior of incomplete notation for the list. @hgwood @frinyvonnick What do you think ? If you are OK, I will comment on #113 in order to refactor array and slice to make the same. I also mutualized the later parsers in only one. |
([beforeBracket, atBracket]) => [[prop, beforeBracket], ...stringToPath(atBracket)], | ||
const pathSegmentEndedByNewSegment = map( | ||
regexp(/^([^.[{]*)\.?([[{]?.*)$/), | ||
([beforeNewSegment, rest]) => [[prop, beforeNewSegment], ...stringToPath(rest)], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice simplification!
regexp(/^(\{[^.[{]*)(.*)$/), | ||
([beforeNewSegment, rest]) => { | ||
return [[prop, beforeNewSegment], ...stringToPath(rest)] | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the lambda could be written in the expression form (ie without braces and return
)?
for (let propMatch = rawProps.match(listPropRegexp); propMatch !== undefined; propMatch = propMatch[5] === '' ? undefined : propMatch[5].match(listPropRegexp)) | ||
props.push(propMatch[2] === undefined ? propMatch[4] : propMatch[2]) | ||
return props.length === 1 ? [[prop, props[0]], ...stringToPath(rest)] : [[list, props], ...stringToPath(rest)] | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This piece of code is a little overwhelming. My advice would be:
- use destructuring to name the elements of
propMatch
- use functional programming to make meaningful transformation names emerge (what is this loop doing? a reduction? a mapping?)
([beforeDot, afterDot]) => [[prop, beforeDot], ...stringToPath(afterDot)], | ||
const listPropRegexp = /^,?((?!["'])([^,]*)|(["'])(.*?[^\\])\3)(.*)/ | ||
const listNotationParser = map( | ||
regexp(/^\{(((?!["'])[^,}]*|(["']).*?[^\\]\2)(,((?!["'])[^,}]*|(["']).*?[^\\]\6))*)\}\.?(.*)$/), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to split the quoted case and the bare case like I did for the bracket notation. I feel it yielded simpler regexes. These ones are a bit hard to read.
@nlepage *their mistake :) That last parser is dead because As for the incomplete cases, I'm fine both ways. |
@hgwood I've used a generator to extract list props, and |
@nlepage i agree for incomplete cases ! |
@nlepage Great improvement to As for splitting the regex, I see now that you cannot really do that as you may have lists with both quoted and unquoted props. I'm still a bit worried by the length of the regex and also the duplication. I think I may have an idea to mitigate that, but I don't want to block this PR on it. My idea is to go full parser combinators to have modular, composable, easy-to-understand parsers so you could describe lists like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌
([beforeDot, afterDot]) => [[prop, beforeDot], ...stringToPath(afterDot)], | ||
const listPropRegexp = /^,?((?!["'])([^,]*)|(["'])(.*?[^\\])\3)(.*)/ | ||
function* extractListProps(rawProps) { | ||
if (rawProps.startsWith(',')) yield '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case isn't tested 😢
const listNotationParser = map( | ||
regexp(/^\{(((?!["'])[^,}]*|(["']).*?[^\\]\2)(,((?!["'])[^,}]*|(["']).*?[^\\]\6))*)\}\.?(.*)$/), | ||
([rawProps, , , , , , rest]) => { | ||
const props = [...extractListProps(rawProps)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smart 💡 !
Nice work 👍 |
Issue : fix #151