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…
	
	Add table
		Add a link
		
	
		Reference in a new issue