difftreelog
feat allow negative indexes in std.slice
in: master
Upstream issue: https://github.com/google/jsonnet/pull/1093
2 files changed
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth234 /// For arrays, nothing will be copied on this call, instead [`ArrValue::Slice`] view will be returned.234 /// For arrays, nothing will be copied on this call, instead [`ArrValue::Slice`] view will be returned.235 pub fn slice(235 pub fn slice(236 self,236 self,237 index: Option<BoundedUsize<0, { i32::MAX as usize }>>,237 index: Option<i32>,238 end: Option<BoundedUsize<0, { i32::MAX as usize }>>,238 end: Option<i32>,239 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,239 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,240 ) -> Result<Self> {240 ) -> Result<Self> {241 match &self {241 match &self {242 IndexableVal::Str(s) => {242 IndexableVal::Str(s) => {243 let mut computed_len = None;243 let index = index.as_deref().copied().unwrap_or(0);244 let mut get_len = || {245 computed_len.map_or_else(246 || {247 let len = s.chars().count();248 let _ = computed_len.insert(len);249 len250 },251 |len| len,252 )253 };254 let mut get_idx = |pos: Option<i32>, default| {255 match pos {256 Some(v) if v < 0 => get_len().saturating_sub((-v) as usize),257 // No need to clamp, as iterator interface is used258 Some(v) => v as usize,259 None => default,260 }261 };262263 let index = get_idx(index, 0);244 let end = end.as_deref().copied().unwrap_or(usize::MAX);264 let end = get_idx(end, usize::MAX);245 let step = step.as_deref().copied().unwrap_or(1);265 let step = step.as_deref().copied().unwrap_or(1);246266247 if index >= end {267 if index >= end {258 ))278 ))259 }279 }260 IndexableVal::Arr(arr) => {280 IndexableVal::Arr(arr) => {261 let index = index.as_deref().copied().unwrap_or(0);281 let get_idx = |pos: Option<i32>, len: usize, default| match pos {282 Some(v) if v < 0 => len.saturating_sub((-v) as usize),283 Some(v) => (v as usize).min(len),284 None => default,285 };286 let index = get_idx(index, arr.len(), 0);262 let end = end.as_deref().copied().unwrap_or(usize::MAX).min(arr.len());287 let end = get_idx(end, arr.len(), arr.len());263 let step = step.as_deref().copied().unwrap_or(1);288 let step = step.as_deref().copied().unwrap_or(1);264289265 if index >= end {290 if index >= end {crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth47#[builtin]47#[builtin]48pub fn builtin_slice(48pub fn builtin_slice(49 indexable: IndexableVal,49 indexable: IndexableVal,50 index: Option<BoundedUsize<0, { i32::MAX as usize }>>,50 index: Option<i32>,51 end: Option<BoundedUsize<0, { i32::MAX as usize }>>,51 end: Option<i32>,52 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,52 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,53) -> Result<Val> {53) -> Result<Val> {54 indexable.slice(index, end, step).map(Val::from)54 indexable.slice(index, end, step).map(Val::from)