diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-10T16·09+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-24T21·25+0000 |
commit | 5685f7c59402439af33f7b6fc1114557f0c33477 (patch) | |
tree | 01dcd1e3df84249c659d5371aaf2ce104fa60af8 /tvix/eval | |
parent | 92c53fe982560248dc7655a5605db5e3cfc35d04 (diff) |
fix(tvix/value): add ident_str representation of strings r/4462
When printing strings as identifiers (in attribute sets), the string should only be quoted and escaped if it contains escape characters. Change-Id: If2bcfa1e93dc8f00be4d7a57ec1d82fc679103c3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6127 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su>
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/value/attrs.rs | 2 | ||||
-rw-r--r-- | tvix/eval/src/value/string.rs | 31 |
2 files changed, 25 insertions, 8 deletions
diff --git a/tvix/eval/src/value/attrs.rs b/tvix/eval/src/value/attrs.rs index 7e3b5f231d66..d04e01bf7eab 100644 --- a/tvix/eval/src/value/attrs.rs +++ b/tvix/eval/src/value/attrs.rs @@ -37,7 +37,7 @@ impl Display for NixAttrs { NixAttrs::Map(map) => { for (name, value) in map { - f.write_fmt(format_args!("{} = {}; ", name, value))?; + f.write_fmt(format_args!("{} = {}; ", name.ident_str(), value))?; } } diff --git a/tvix/eval/src/value/string.rs b/tvix/eval/src/value/string.rs index 0b665a0a5ec6..72f146765778 100644 --- a/tvix/eval/src/value/string.rs +++ b/tvix/eval/src/value/string.rs @@ -43,6 +43,26 @@ impl NixString { NixString::Heap(s) => s, } } + + // Return a displayable representation of the string as an + // identifier. + // + // This is used when printing out strings used as e.g. attribute + // set keys, as those are only escaped in the presence of special + // characters. + pub fn ident_str(&self) -> Cow<str> { + let escaped = nix_escape_string(self.as_str()); + + match escaped { + // A borrowed string is unchanged and can be returned as + // is. + Cow::Borrowed(_) => escaped, + + // An owned string has escapes, and needs the outer quotes + // for display. + Cow::Owned(s) => Cow::Owned(format!("\"{}\"", s)), + } + } } fn nix_escape_char(ch: char) -> Option<&'static str> { @@ -54,11 +74,11 @@ fn nix_escape_char(ch: char) -> Option<&'static str> { } } -// Escape a Nix string for display, as the user-visible representation -// is always an escaped string (except for traces). +// Escape a Nix string for display, as most user-visible representation +// are escaped strings. // // Note that this does not add the outer pair of surrounding quotes. -fn escape_string(input: &str) -> Cow<str> { +fn nix_escape_string(input: &str) -> Cow<str> { for (i, c) in input.chars().enumerate() { if let Some(esc) = nix_escape_char(c) { let mut escaped = String::with_capacity(input.len()); @@ -82,10 +102,7 @@ fn escape_string(input: &str) -> Cow<str> { impl Display for NixString { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("\"")?; - match self { - NixString::Static(s) => f.write_str(&escape_string(s))?, - NixString::Heap(s) => f.write_str(&escape_string(s))?, - }; + f.write_str(&nix_escape_string(self.as_str()))?; f.write_str("\"") } } |