substitute_one_step: stop after first variable has been substituted#11
substitute_one_step: stop after first variable has been substituted#11cre4ture wants to merge 1 commit intofizyr:mainfrom
Conversation
|
Hey! Sounds interesting. But maybe we can make it return a tuple of 3 slices instead of a |
1f21449 to
06209a3
Compare
06209a3 to
3efe2a4
Compare
|
You where right, the interface was a bit mixed up. I did refactorings and I think this fits now more to your idea. |
|
I think we still need to prevent returning a But I also wonder, do you still need |
| assert_eq!( | ||
| Ok("Hello cruel world!"), | ||
| substitute("Hello ${not_name:cruel $name}!", &map).as_deref() | ||
| ); |
There was a problem hiding this comment.
Don't replace these. The check!() and assert!() macros from assert2 give far better error messages than assert_eq!().
|
|
||
| let_assert!(Ok(expanded) = substitute("one ${aap}", variables)); | ||
| assert!(expanded == "one noot"); | ||
| assert_eq!(expanded, "one noot"); |
There was a problem hiding this comment.
Same here, don't change this. assert2::assert!() is better.
| assert_eq!(result.0, "subst"); | ||
| assert_eq!(result.1.slice_before_ends, 6); | ||
| assert_eq!(result.1.slice_after_starts, 11); | ||
| assert_eq!(result.1.subst_type, SubstitutionType::Variable); |
There was a problem hiding this comment.
| assert_eq!(result.0, "subst"); | |
| assert_eq!(result.1.slice_before_ends, 6); | |
| assert_eq!(result.1.slice_after_starts, 11); | |
| assert_eq!(result.1.subst_type, SubstitutionType::Variable); | |
| assert!(result.0 == "subst"); | |
| assert!(result.1.slice_before_ends == 6); | |
| assert!(result.1.slice_after_starts == 11); | |
| assert!(result.1.subst_type == SubstitutionType::Variable); |
| variables.insert(String::from("NAME"), String::from("subst")); | ||
|
|
||
| let source = r"hello $NAME. Nice\$to meet you $NAME."; | ||
| let result = substitute_one_step(source, &variables).unwrap().unwrap(); |
There was a problem hiding this comment.
| let result = substitute_one_step(source, &variables).unwrap().unwrap(); | |
| let_assert!(Ok(Some(result)) = substitute_one_step(source, &variables)); |
| let result = substitute_one_step(source.get(result.1.slice_after_starts..).unwrap(), &variables) | ||
| .unwrap() | ||
| .unwrap(); | ||
| assert_eq!(result.0, "$"); | ||
| assert_eq!(result.1.slice_before_ends, 6); | ||
| assert_eq!(result.1.slice_after_starts, 8); | ||
| assert_eq!(result.1.subst_type, SubstitutionType::UnescapeOne); |
There was a problem hiding this comment.
| let result = substitute_one_step(source.get(result.1.slice_after_starts..).unwrap(), &variables) | |
| .unwrap() | |
| .unwrap(); | |
| assert_eq!(result.0, "$"); | |
| assert_eq!(result.1.slice_before_ends, 6); | |
| assert_eq!(result.1.slice_after_starts, 8); | |
| assert_eq!(result.1.subst_type, SubstitutionType::UnescapeOne); | |
| let_assert!(Ok(Some(result)) = substitute_one_step(source.get(result.1.slice_after_starts..).unwrap(), &variables)); | |
| assert!(result.0 == "$"); | |
| assert!(result.1.slice_before_ends == 6); | |
| assert!(result.1.slice_after_starts == 8); | |
| assert!(result.1.subst_type == SubstitutionType::UnescapeOne); |
| let result = substitute_one_step(source, &variables).unwrap(); | ||
| assert!(result.is_none()); |
There was a problem hiding this comment.
| let result = substitute_one_step(source, &variables).unwrap(); | |
| assert!(result.is_none()); | |
| assert!(let Ok(None) = substitute_one_step(source, &variables)); |
I would still need a funktion like But we can go for the template based approach anyway if you like. Just let me know what you thing about #14 |
I think I'm not entirely seeing your use case clearly. It feels somewhat odd to perform only partial variable substitution. Wouldn't it make more sense to run your own parser, and then run the substitution on the relevant parts that your parser indicates? Or maybe the opposite makes sense: parse a full template first, and then run your parser on the non-variable parts of the template? Do you have a link to how you're using this maybe? Or otherwise could you explain with some pseudo-code how this is supposed to integrate with your parser?
I will! Probably not today though, as I'm on holiday :p So I have only limited time for reviews. But the comments about the unit tests apply to both PRs. If you have the time you could already process those. |
|
This pull request contains (temporarily) the modified subst such that it works. If you like you can have a look at it: I think the main problems I encountered when I tried to use the unmodified subst where these:
With the "one-step" way, I just need to stop at an unescaped $ and call subst_one_step which tells me about the end of the variable name and the substituted value. In the beginning, when I didn't know the subst source code that well, for me the easiest way to achieve my goal was to provide access to this single/one-substitution step. Now, as I know your code pretty well, I detected that maybe the only function that I need from subst is the |
|
Hmm, interesting. I still like the template approach, but I also like to unblock progress for |
This change provides the posibility to only replace the next variable in a given string, returning the position after the variable name.
This is usefull if the substitution is to be integrated into an existing string parsing statemachine.
E.g. I'm integrating in into a "shell-words" like funktionality needed by the uutils/coreutils-env app.
To avoid that we need to do a fork of your code, we want to bring it into your main branch.
Please tell me what you think.
Kind regards