fix(tvix/value): add escaping logic for Nix strings
Nix strings displayed to users must be escaped the same way as they are in C++ Nix. This adds the scaffolding for escapes, but is most likely not yet complete. Change-Id: Icfdcb2ac98d292c567ba894a92b6529a53e0cc17 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6124 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
This commit is contained in:
parent
a2b4b4a485
commit
4c9aad17ad
1 changed files with 46 additions and 10 deletions
|
@ -1,4 +1,4 @@
|
|||
use std::fmt::Display;
|
||||
use std::{borrow::Cow, fmt::Display};
|
||||
|
||||
/// This module implements Nix language strings and their different
|
||||
/// backing implementations.
|
||||
|
@ -9,15 +9,6 @@ pub enum NixString {
|
|||
Heap(String),
|
||||
}
|
||||
|
||||
impl Display for NixString {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
NixString::Static(s) => f.write_str(s),
|
||||
NixString::Heap(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for NixString {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_str() == other.as_str()
|
||||
|
@ -53,3 +44,48 @@ impl NixString {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn nix_escape_char(ch: char) -> Option<&'static str> {
|
||||
match ch {
|
||||
'\\' => Some("\\"),
|
||||
'"' => Some("\\"),
|
||||
'\n' => Some("\\n"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Escape a Nix string for display, as the user-visible representation
|
||||
// is always an escaped string (except for traces).
|
||||
//
|
||||
// Note that this does not add the outer pair of surrounding quotes.
|
||||
fn 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());
|
||||
escaped.push_str(&input[..i]);
|
||||
escaped.push_str(esc);
|
||||
|
||||
for c in input[i + 1..].chars() {
|
||||
match nix_escape_char(c) {
|
||||
Some(esc) => escaped.push_str(esc),
|
||||
None => escaped.push(c),
|
||||
}
|
||||
}
|
||||
|
||||
return Cow::Owned(escaped);
|
||||
}
|
||||
}
|
||||
|
||||
Cow::Borrowed(input)
|
||||
}
|
||||
|
||||
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("\"")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue