difftreelog
fix accept null as std.slice argument/in slicing syntax
in: master
3 files changed
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth655 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 }crates/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;
crates/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]