difftreelog
feat make std.map accept strings
in: master
5 files changed
crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth1use std::rc::Rc;21use jrsonnet_gcmodule::{Cc, Trace};3use jrsonnet_gcmodule::{Cc, Trace};2use jrsonnet_interner::IBytes;4use jrsonnet_interner::IBytes;14pub enum ArrValue {16pub enum ArrValue {15 /// Layout optimized byte array.17 /// Layout optimized byte array.16 Bytes(BytesArray),18 Bytes(BytesArray),19 /// Layout optimized char array.20 Chars(CharArray),17 /// Every element is lazy evaluated.21 /// Every element is lazy evaluated.18 Lazy(LazyArray),22 Lazy(LazyArray),19 /// Every element is defined somewhere in source code23 /// Every element is defined somewhere in source code66 pub fn bytes(bytes: IBytes) -> Self {70 pub fn bytes(bytes: IBytes) -> Self {67 Self::Bytes(BytesArray(bytes))71 Self::Bytes(BytesArray(bytes))68 }72 }73 pub fn chars(chars: impl Iterator<Item = char>) -> Self {74 Self::Chars(CharArray(Rc::new(chars.collect())))75 }697670 #[must_use]77 #[must_use]71 pub fn map(self, mapper: FuncVal) -> Self {78 pub fn map(self, mapper: FuncVal) -> Self {237 /// Is this vec supports `.get_cheap()?`244 /// Is this vec supports `.get_cheap()?`238 pub fn is_cheap(&self) -> bool {245 pub fn is_cheap(&self) -> bool {239 match self {246 match self {240 ArrValue::Eager(_) | ArrValue::Range(..) | ArrValue::Bytes(_) => true,247 ArrValue::Eager(_) | ArrValue::Range(..) | ArrValue::Bytes(_) | ArrValue::Chars(_) => {248 true249 }241 ArrValue::Extended(v) => v.a.is_cheap() && v.b.is_cheap(),250 ArrValue::Extended(v) => v.a.is_cheap() && v.b.is_cheap(),242 ArrValue::Slice(r) => r.inner.is_cheap(),251 ArrValue::Slice(r) => r.inner.is_cheap(),243 ArrValue::Reverse(i) => i.0.is_cheap(),252 ArrValue::Reverse(i) => i.0.is_cheap(),crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth1//! Those implementations are a bit sketchy, as this is mostly performance experiments1//! Those implementations are a bit sketchy, as this is mostly performance experiments2//! of not yet finished nightly rust features2//! of not yet finished nightly rust features334use std::{cell::RefCell, iter, mem::replace};4use std::{cell::RefCell, iter, mem::replace, rc::Rc};556use jrsonnet_gcmodule::{Cc, Trace};6use jrsonnet_gcmodule::{Cc, Trace};7use jrsonnet_interner::IBytes;7use jrsonnet_interner::{IBytes, IStr};8use jrsonnet_parser::LocExpr;8use jrsonnet_parser::LocExpr;9910use super::ArrValue;10use super::ArrValue;11use crate::{11use crate::{12 error::ErrorKind::InfiniteRecursionDetected, evaluate, function::FuncVal, val::ThunkValue,12 error::ErrorKind::InfiniteRecursionDetected,13 evaluate,14 function::FuncVal,15 val::{StrValue, ThunkValue},13 Context, Error, Result, Thunk, Val,16 Context, Error, Result, Thunk, Val,14};17};1518153 }156 }154}157}158159#[derive(Trace, Debug, Clone)]160pub struct CharArray(pub Rc<Vec<char>>);161#[cfg(feature = "nightly")]162type CharArrayIter<'t> = impl DoubleEndedIterator<Item = Result<Val>> + ExactSizeIterator + 't;163#[cfg(feature = "nightly")]164type CharArrayLazyIter<'t> = impl DoubleEndedIterator<Item = Thunk<Val>> + ExactSizeIterator + 't;165#[cfg(feature = "nightly")]166type CharArrayCheapIter<'t> = impl DoubleEndedIterator<Item = Val> + ExactSizeIterator + 't;167impl ArrayLike for CharArray {168 #[cfg(feature = "nightly")]169 type Iter<'t> = CharArrayIter<'t>;170 #[cfg(feature = "nightly")]171 type IterLazy<'t> = CharArrayLazyIter<'t>;172 #[cfg(feature = "nightly")]173 type IterCheap<'t> = CharArrayCheapIter<'t>;174175 fn len(&self) -> usize {176 self.0.len()177 }178179 fn get(&self, index: usize) -> Result<Option<Val>> {180 Ok(self.get_cheap(index))181 }182183 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {184 self.get_cheap(index).map(Thunk::evaluated)185 }186187 fn get_cheap(&self, index: usize) -> Option<Val> {188 self.0189 .get(index)190 .map(|v| Val::Str(StrValue::Flat(IStr::from(*v))))191 }192193 #[cfg(feature = "nightly")]194 fn iter(&self) -> CharArrayIter<'_> {195 self.0196 .iter()197 .map(|v| Ok(Val::Str(StrValue::Flat(IStr::from(*v)))))198 }199200 #[cfg(feature = "nightly")]201 fn iter_lazy(&self) -> CharArrayLazyIter<'_> {202 self.0203 .iter()204 .map(|v| Thunk::evaluated(Val::Str(StrValue::Flat(IStr::from(*v)))))205 }206207 #[cfg(feature = "nightly")]208 fn iter_cheap(&self) -> Option<CharArrayCheapIter<'_>> {209 Some(210 self.0211 .iter()212 .map(|v| Val::Str(StrValue::Flat(IStr::from(*v)))),213 )214 }215}216impl From<CharArray> for ArrValue {217 fn from(value: CharArray) -> Self {218 ArrValue::Chars(value)219 }220}155221156#[derive(Trace, Debug, Clone)]222#[derive(Trace, Debug, Clone)]157pub struct BytesArray(pub IBytes);223pub struct BytesArray(pub IBytes);935 ($t:ident.$m:ident($($ident:ident),*)) => {1001 ($t:ident.$m:ident($($ident:ident),*)) => {936 match $t {1002 match $t {937 Self::Bytes(e) => e.$m($($ident)*),1003 Self::Bytes(e) => e.$m($($ident)*),1004 Self::Chars(e) => e.$m($($ident)*),938 Self::Expr(e) => e.$m($($ident)*),1005 Self::Expr(e) => e.$m($($ident)*),939 Self::Lazy(e) => e.$m($($ident)*),1006 Self::Lazy(e) => e.$m($($ident)*),940 Self::Eager(e) => e.$m($($ident)*),1007 Self::Eager(e) => e.$m($($ident)*),crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth149 Arr(ArrValue),149 Arr(ArrValue),150}150}151impl IndexableVal {151impl IndexableVal {152 pub fn to_array(self) -> ArrValue {153 match self {154 IndexableVal::Str(s) => ArrValue::chars(s.chars()),155 IndexableVal::Arr(arr) => arr,156 }157 }152 /// Slice the value.158 /// Slice the value.153 ///159 ///154 /// # Implementation160 /// # Implementationcrates/jrsonnet-interner/src/lib.rsdiffbeforeafterboth205 s.as_str().into()205 s.as_str().into()206 }206 }207}207}208impl From<char> for IStr {209 fn from(value: char) -> Self {210 let mut buf = [0; 5];211 Self::from(&*value.encode_utf8(&mut buf))212 }213}208impl From<&[u8]> for IBytes {214impl From<&[u8]> for IBytes {209 fn from(v: &[u8]) -> Self {215 fn from(v: &[u8]) -> Self {210 intern_bytes(v)216 intern_bytes(v)crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth45}45}464647#[builtin]47#[builtin]48pub fn builtin_map(func: FuncVal, arr: ArrValue) -> Result<ArrValue> {48pub fn builtin_map(func: FuncVal, arr: IndexableVal) -> ArrValue {49 let arr = arr.to_array();49 Ok(arr.map(func))50 arr.map(func)50}51}515252#[builtin]53#[builtin]