diff options
author | Adam Joseph <adam@westernsemico.com> | 2022-10-25T08·56-0700 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2022-11-04T01·42+0000 |
commit | 4ec43bed5e1f6077402301aeee125870f755267b (patch) | |
tree | ae865efb7c87bdd4705f65f278c4d98212e8d3b8 /tvix/eval/src/value/string.rs | |
parent | d8841376e733e53af234bd924d7841c34d9b0c61 (diff) |
fix(tvix/eval): quote keys which are not valid identifiers r/5241
The impl Display for NixAttrs needs to wrap double quotes around any keys which are not valid Nix identifiers. This commit does that, and adds a test (which fails prior to this commit and passes after this commit). Change-Id: Ie31ce91e8637cb27073f23f115db81feefdc6424 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7084 Autosubmit: Adam Joseph <adam@westernsemico.com> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/value/string.rs')
-rw-r--r-- | tvix/eval/src/value/string.rs | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/tvix/eval/src/value/string.rs b/tvix/eval/src/value/string.rs index 4caef653f2cc..66697a7f2f4f 100644 --- a/tvix/eval/src/value/string.rs +++ b/tvix/eval/src/value/string.rs @@ -118,7 +118,13 @@ impl NixString { match escaped { // A borrowed string is unchanged and can be returned as // is. - Cow::Borrowed(_) => escaped, + Cow::Borrowed(_) => { + if is_valid_nix_identifier(&escaped) { + escaped + } else { + Cow::Owned(format!("\"{}\"", escaped)) + } + } // An owned string has escapes, and needs the outer quotes // for display. @@ -152,6 +158,23 @@ fn nix_escape_char(ch: char, next: Option<&char>) -> Option<&'static str> { } } +/// Return true if this string can be used as an identifier in Nix. +fn is_valid_nix_identifier(s: &str) -> bool { + // adapted from rnix-parser's tokenizer.rs + let mut chars = s.chars(); + match chars.next() { + Some('a'..='z' | 'A'..='Z' | '_') => (), + _ => return false, + } + for c in chars { + match c { + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-' => (), + _ => return false, + } + } + return true; +} + /// Escape a Nix string for display, as most user-visible representation /// are escaped strings. /// |