difftreelog
refactor drop CharArray
in: master
5 files changed
crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth1use std::{2 any::Any,3 fmt::{self},4 num::NonZeroU32,5 rc::Rc,6};78use jrsonnet_gcmodule::{Cc, cc_dyn};9use jrsonnet_ir::Expr;1011use crate::{Context, Result, Thunk, Val, function::NativeFn, typed::IntoUntyped};1213mod spec;14pub use spec::{ArrayLike, *};1516cc_dyn!(17 #[doc = "Represents a Jsonnet array value."]18 #[derive(Clone)]19 ArrValue,20 ArrayLike,21 pub fn new() {...}22);23impl fmt::Debug for ArrValue {24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {25 self.0.fmt(f)26 }27}2829pub trait ArrayLikeIter<T>: Iterator<Item = T> + DoubleEndedIterator + ExactSizeIterator {}30impl<I, T> ArrayLikeIter<T> for I where31 I: Iterator<Item = T> + DoubleEndedIterator + ExactSizeIterator32{33}3435impl ArrValue {36 pub fn empty() -> Self {37 Self::new(())38 }3940 pub fn expr(ctx: Context, exprs: Rc<Vec<Expr>>) -> Self {41 Self::new(ExprArray::new(ctx, exprs))42 }4344 pub fn repeated(data: Self, repeats: usize) -> Option<Self> {45 Some(Self::new(RepeatedArray::new(data, repeats)?))46 }4748 pub fn chars(chars: impl Iterator<Item = char>) -> Self {49 Self::new(CharArray(chars.collect()))50 }5152 #[must_use]53 pub fn map(self, mapper: NativeFn!((Val) -> Val)) -> Self {54 Self::new(<MappedArray>::new(self, ArrayMapper::Plain(mapper)))55 }5657 #[must_use]58 pub fn map_with_index(self, mapper: NativeFn!((u32, Val) -> Val)) -> Self {59 Self::new(<MappedArray>::new(self, ArrayMapper::WithIndex(mapper)))60 }6162 pub fn filter(self, filter: NativeFn!((Thunk<Val>) -> bool)) -> Result<Self> {63 // TODO: ArrValue::Picked(inner, indexes) for large arrays64 'eager: {65 let mut out = Vec::new();66 for i in self.iter() {67 let Ok(i) = i else {68 break 'eager;69 };70 if filter.call(IntoUntyped::into_lazy_untyped(i.clone()))? {71 out.push(i);72 }73 }74 return Ok(Self::new(out));75 };7677 let mut out = Vec::new();78 for i in self.iter_lazy() {79 if filter.call(i.clone())? {80 out.push(i);81 }82 }83 Ok(Self::new(out))84 }8586 pub fn extended(a: Self, b: Self) -> Self {87 if a.is_empty() {88 b89 } else if b.is_empty() {90 a91 } else {92 Self::new(ExtendedArray::new(a, b))93 }94 }9596 pub fn range_exclusive(a: i32, b: i32) -> Self {97 Self::new(RangeArray::new_exclusive(a, b))98 }99 pub fn range_inclusive(a: i32, b: i32) -> Self {100 Self::new(RangeArray::new_inclusive(a, b))101 }102103 #[must_use]104 pub fn slice(self, index: Option<i32>, end: Option<i32>, step: Option<NonZeroU32>) -> Self {105 let get_idx = |pos: Option<i32>, len: usize, default| match pos {106 #[expect(107 clippy::cast_sign_loss,108 reason = "abs value is used, len is limited to u31"109 )]110 Some(v) if v < 0 => len.saturating_sub((-v) as usize),111 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]112 Some(v) => (v as usize).min(len),113 None => default,114 };115 let index = get_idx(index, self.len(), 0);116 let end = get_idx(end, self.len(), self.len());117 let step = step.unwrap_or_else(|| NonZeroU32::new(1).expect("1 != 0"));118119 if index >= end {120 return Self::empty();121 }122123 Self::new(SliceArray {124 inner: self,125 #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]126 from: index as u32,127 #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]128 to: end as u32,129 step: step.get(),130 })131 }132133 /// Array length.134 pub fn len(&self) -> usize {135 self.0.len()136 }137138 /// Is array contains no elements?139 pub fn is_empty(&self) -> bool {140 self.0.is_empty()141 }142143 pub fn is_cheap(&self) -> bool {144 self.0.is_cheap()145 }146147 /// Get array element by index, evaluating it, if it is lazy.148 ///149 /// Returns `None` on out-of-bounds condition.150 pub fn get(&self, index: usize) -> Result<Option<Val>> {151 self.0.get(index)152 }153154 /// Get array element by index, without evaluation.155 ///156 /// Returns `None` on out-of-bounds condition.157 pub fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {158 self.0.get_lazy(index)159 }160161 pub fn iter(&self) -> impl ArrayLikeIter<Result<Val>> + '_ {162 (0..self.len()).map(|i| self.get(i).transpose().expect("length checked"))163 }164165 /// Iterate over elements, returning lazy values.166 pub fn iter_lazy(&self) -> impl ArrayLikeIter<Thunk<Val>> + '_ {167 (0..self.len()).map(|i| self.get_lazy(i).expect("length checked"))168 }169170 /// Return a reversed view on current array.171 #[must_use]172 pub fn reversed(self) -> Self {173 Self::new(ReverseArray(self))174 }175176 pub fn ptr_eq(a: &Self, b: &Self) -> bool {177 Cc::ptr_eq(&a.0, &b.0)178 }179180 pub fn as_any(&self) -> &dyn Any {181 &self.0182 }183}184impl<T> From<T> for ArrValue185where186 T: ArrayLike,187{188 fn from(value: T) -> Self {189 Self::new(value)190 }191}192impl<I> FromIterator<I> for ArrValue193where194 Vec<I>: ArrayLike,195{196 fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {197 Self::new(iter.into_iter().collect::<Vec<_>>())198 }199}crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/spec.rs
+++ b/crates/jrsonnet-evaluator/src/arr/spec.rs
@@ -97,17 +97,6 @@
}
}
-#[derive(Trace, Debug)]
-pub struct CharArray(pub Vec<char>);
-impl ArrayCheap for CharArray {
- fn len(&self) -> usize {
- self.0.as_slice().len()
- }
- fn get(&self, index: usize) -> Option<Val> {
- self.0.as_slice().get(index).map(|v| Val::string(*v))
- }
-}
-
impl ArrayCheap for IBytes {
fn len(&self) -> usize {
self.as_slice().len()
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -463,6 +463,11 @@
impl Typed for char {
const TYPE: &'static ComplexValType = &ComplexValType::Char;
}
+impl IntoUntyped for &char {
+ fn into_untyped(value: Self) -> Result<Val> {
+ Ok(Val::string(*value))
+ }
+}
impl IntoUntyped for char {
fn into_untyped(value: Self) -> Result<Val> {
Ok(Val::string(value))
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -266,7 +266,7 @@
pub fn to_array(self) -> ArrValue {
match self {
- Self::Str(s) => ArrValue::chars(s.chars()),
+ Self::Str(s) => s.chars().collect(),
Self::Arr(arr) => arr,
}
}
crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/strings.rs
+++ b/crates/jrsonnet-stdlib/src/strings.rs
@@ -223,7 +223,7 @@
#[builtin]
pub fn builtin_string_chars(str: IStr) -> ArrValue {
- ArrValue::chars(str.chars())
+ str.chars().collect()
}
#[builtin]