difftreelog
feat impl Typed for BTreeMap
in: master
2 files changed
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -347,6 +347,51 @@
}
}
+impl<K: Typed + Ord, V: Typed> Typed for BTreeMap<K, V> {
+ const TYPE: &'static ComplexValType = &ComplexValType::AttrsOf(V::TYPE);
+
+ fn into_untyped(typed: Self) -> Result<Val> {
+ let mut out = ObjValueBuilder::with_capacity(typed.len());
+ for (k, v) in typed {
+ let Some(key) = K::into_untyped(k)?.as_str() else {
+ throw!("map key should serialize to string");
+ };
+ let value = V::into_untyped(v)?;
+ out.member(key).value_unchecked(value);
+ }
+ Ok(Val::Obj(out.build()))
+ }
+
+ fn from_untyped(value: Val) -> Result<Self> {
+ Self::TYPE.check(&value)?;
+ let obj = value.as_obj().expect("typecheck should fail");
+
+ let mut out = BTreeMap::new();
+ if V::wants_lazy() {
+ for key in obj.fields_ex(
+ false,
+ #[cfg(feature = "exp-preserve-order")]
+ false,
+ ) {
+ let value = obj.get_lazy(key.clone()).expect("field exists");
+ let value = V::from_lazy_untyped(value)?;
+ let key = K::from_untyped(Val::Str(key.into()))?;
+ let _ = out.insert(key, value);
+ }
+ } else {
+ for (key, value) in obj.iter(
+ #[cfg(feature = "exp-preserve-order")]
+ false,
+ ) {
+ let key = K::from_untyped(Val::Str(key.into()))?;
+ let value = V::from_untyped(value?)?;
+ let _ = out.insert(key, value);
+ }
+ }
+ Ok(out)
+ }
+}
+
impl Typed for Val {
const TYPE: &'static ComplexValType = &ComplexValType::Any;
crates/jrsonnet-evaluator/src/typed/mod.rsdiffbeforeafterboth191 }191 }192 v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),192 v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),193 },193 },194 Self::AttrsOf(a) => match value {195 Val::Obj(o) => {196 for (_key, value) in o.iter(197 #[cfg(feature = "exp-preserve-order")]198 false,199 ) {200 let value = value?;201 a.check(&value)?;202 }203 Ok(())204 }205 v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),206 },194 Self::ObjectRef(elems) => match value {207 Self::ObjectRef(elems) => match value {195 Val::Obj(obj) => {208 Val::Obj(obj) => {196 for (k, v) in elems.iter() {209 for (k, v) in elems.iter() {