git.delta.rocks / jrsonnet / refs/commits / e46de0a3e23e

difftreelog

fix accept null as std.slice argument/in slicing syntax

Yaroslav Bolyukin2024-11-03parent: #7160d47.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
655 desc: &'static str,655 desc: &'static str,
656 ) -> Result<Option<T>> {656 ) -> Result<Option<T>> {
657 if let Some(value) = expr {657 if let Some(value) = expr {
658 Ok(Some(in_frame(658 Ok(in_frame(
659 loc,659 loc,
660 || format!("slice {desc}"),660 || format!("slice {desc}"),
661 || T::from_untyped(evaluate(ctx.clone(), value)?),661 || <Option<T>>::from_untyped(evaluate(ctx.clone(), value)?),
662 )?))662 )?)
663 } else {663 } else {
664 Ok(None)664 Ok(None)
665 }665 }
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -655,6 +655,26 @@
 	}
 }
 
+impl<T> Typed for Option<T>
+where
+	T: Typed,
+{
+	const TYPE: &'static ComplexValType =
+		&ComplexValType::UnionRef(&[&ComplexValType::Simple(ValType::Null), T::TYPE]);
+
+	fn into_untyped(typed: Self) -> Result<Val> {
+		typed.map_or_else(|| Ok(Val::Null), |v| T::into_untyped(v))
+	}
+
+	fn from_untyped(untyped: Val) -> Result<Self> {
+		if matches!(untyped, Val::Null) {
+			Ok(None)
+		} else {
+			T::from_untyped(untyped).map(Some)
+		}
+	}
+}
+
 pub struct NativeFn<D: NativeDesc>(D::Value);
 impl<D: NativeDesc> Deref for NativeFn<D> {
 	type Target = D::Value;
modifiedcrates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -48,11 +48,13 @@
 #[builtin]
 pub fn builtin_slice(
 	indexable: IndexableVal,
-	index: Option<i32>,
-	end: Option<i32>,
-	step: Option<BoundedUsize<1, { i32::MAX as usize }>>,
+	index: Option<Option<i32>>,
+	end: Option<Option<i32>>,
+	step: Option<Option<BoundedUsize<1, { i32::MAX as usize }>>>,
 ) -> Result<Val> {
-	indexable.slice(index, end, step).map(Val::from)
+	indexable
+		.slice(index.flatten(), end.flatten(), step.flatten())
+		.map(Val::from)
 }
 
 #[builtin]