Skip to content

Commit

Permalink
fix: accept null as std.slice argument/in slicing syntax
Browse files Browse the repository at this point in the history
Fixes: #176
  • Loading branch information
CertainLach committed Nov 3, 2024
1 parent 7160d47 commit e46de0a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
6 changes: 3 additions & 3 deletions crates/jrsonnet-evaluator/src/evaluate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,11 +655,11 @@ pub fn evaluate(ctx: Context, expr: &LocExpr) -> Result<Val> {
desc: &'static str,
) -> Result<Option<T>> {
if let Some(value) = expr {
Ok(Some(in_frame(
Ok(in_frame(
loc,
|| format!("slice {desc}"),
|| T::from_untyped(evaluate(ctx.clone(), value)?),
)?))
|| <Option<T>>::from_untyped(evaluate(ctx.clone(), value)?),
)?)
} else {
Ok(None)
}
Expand Down
20 changes: 20 additions & 0 deletions crates/jrsonnet-evaluator/src/typed/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,26 @@ impl Typed for Null {
}
}

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;
Expand Down
10 changes: 6 additions & 4 deletions crates/jrsonnet-stdlib/src/arrays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ pub fn builtin_repeat(what: Either![IStr, ArrValue], count: usize) -> Result<Val
#[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]
Expand Down

0 comments on commit e46de0a

Please sign in to comment.