diff options
Diffstat (limited to 'tvix/serde')
-rw-r--r-- | tvix/serde/Cargo.toml | 3 | ||||
-rw-r--r-- | tvix/serde/src/de.rs | 28 | ||||
-rw-r--r-- | tvix/serde/src/de_tests.rs | 3 |
3 files changed, 25 insertions, 9 deletions
diff --git a/tvix/serde/Cargo.toml b/tvix/serde/Cargo.toml index e535f6e8a397..5652126ada1d 100644 --- a/tvix/serde/Cargo.toml +++ b/tvix/serde/Cargo.toml @@ -5,4 +5,5 @@ edition = "2021" [dependencies] tvix-eval = { path = "../eval" } -serde = { version = "1.0", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } +bstr = { version = "1.8.0", features = ["serde"] } diff --git a/tvix/serde/src/de.rs b/tvix/serde/src/de.rs index 15ab07c536d0..cf85ffab2e81 100644 --- a/tvix/serde/src/de.rs +++ b/tvix/serde/src/de.rs @@ -1,5 +1,6 @@ //! Deserialisation from Nix to Rust values. +use bstr::ByteSlice; use serde::de::value::{MapDeserializer, SeqDeserializer}; use serde::de::{self, EnumAccess, VariantAccess}; pub use tvix_eval::Evaluation; @@ -209,7 +210,7 @@ impl<'de> de::Deserializer<'de> for NixDeserializer { V: de::Visitor<'de>, { if let Value::String(s) = &self.value { - let chars = s.as_str().chars().collect::<Vec<_>>(); + let chars = s.chars().collect::<Vec<_>>(); if chars.len() == 1 { return visitor.visit_char(chars[0]); } @@ -223,7 +224,9 @@ impl<'de> de::Deserializer<'de> for NixDeserializer { V: de::Visitor<'de>, { if let Value::String(s) = &self.value { - return visitor.visit_str(s.as_str()); + if let Ok(s) = s.to_str() { + return visitor.visit_str(s); + } } Err(unexpected("string", &self.value)) @@ -234,7 +237,9 @@ impl<'de> de::Deserializer<'de> for NixDeserializer { V: de::Visitor<'de>, { if let Value::String(s) = &self.value { - return visitor.visit_str(s.as_str()); + if let Ok(s) = s.to_str() { + return visitor.visit_str(s); + } } Err(unexpected("string", &self.value)) @@ -379,7 +384,13 @@ impl<'de> de::Deserializer<'de> for NixDeserializer { { match self.value { // a string represents a unit variant - Value::String(s) => visitor.visit_enum(de::value::StrDeserializer::new(s.as_str())), + Value::String(ref s) => { + if let Ok(s) = s.to_str() { + visitor.visit_enum(de::value::StrDeserializer::new(s)) + } else { + Err(unexpected(name, &self.value)) + } + } // an attribute set however represents an externally // tagged enum with content @@ -420,9 +431,12 @@ impl<'de> EnumAccess<'de> for Enum { } let (key, value) = self.0.into_iter().next().expect("length asserted above"); - let val = seed.deserialize(de::value::StrDeserializer::<Error>::new(key.as_str()))?; - - Ok((val, NixDeserializer::new(value))) + if let Ok(k) = key.to_str() { + let val = seed.deserialize(de::value::StrDeserializer::<Error>::new(k))?; + Ok((val, NixDeserializer::new(value))) + } else { + Err(unexpected("string", &key.clone().into())) + } } } diff --git a/tvix/serde/src/de_tests.rs b/tvix/serde/src/de_tests.rs index 807d953c77fa..54c2fdf8f7fe 100644 --- a/tvix/serde/src/de_tests.rs +++ b/tvix/serde/src/de_tests.rs @@ -213,6 +213,7 @@ fn deserialize_with_config() { #[builtins] mod test_builtins { + use bstr::ByteSlice; use tvix_eval::generators::{Gen, GenCo}; use tvix_eval::{ErrorKind, NixString, Value}; @@ -220,7 +221,7 @@ mod test_builtins { pub async fn builtin_prepend_hello(co: GenCo, x: Value) -> Result<Value, ErrorKind> { match x { Value::String(s) => { - let new_string = NixString::from(format!("hello {}", s.as_str())); + let new_string = NixString::from(format!("hello {}", s.to_str().unwrap())); Ok(Value::String(new_string)) } _ => Err(ErrorKind::TypeError { |