From 5685f7c59402439af33f7b6fc1114557f0c33477 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 10 Aug 2022 19:09:27 +0300 Subject: fix(tvix/value): add ident_str representation of strings 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 Autosubmit: tazjin --- tvix/eval/src/value/attrs.rs | 2 +- tvix/eval/src/value/string.rs | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'tvix/eval') 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 { + 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 { +fn nix_escape_string(input: &str) -> Cow { 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 { 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("\"") } } -- cgit 1.4.1