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
 | /// This module implements Nix language strings and their different
 | ||||||
| /// backing implementations.
 | /// backing implementations.
 | ||||||
|  | @ -9,15 +9,6 @@ pub enum NixString { | ||||||
|     Heap(String), |     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 { | impl PartialEq for NixString { | ||||||
|     fn eq(&self, other: &Self) -> bool { |     fn eq(&self, other: &Self) -> bool { | ||||||
|         self.as_str() == other.as_str() |         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…
	
	Add table
		Add a link
		
	
		Reference in a new issue