difftreelog
refactor split Typed into FromUntyped and IntoUntyped
in: master
20 files changed
bindings/jsonnet/src/native.rsdiffbeforeafterboth6use jrsonnet_evaluator::{6use jrsonnet_evaluator::{7 error::{Error, ErrorKind},7 error::{Error, ErrorKind},8 function::builtin::{NativeCallback, NativeCallbackHandler},8 function::builtin::{NativeCallback, NativeCallbackHandler},9 typed::Typed,9 typed::FromUntyped as _,10 IStr, Val,10 IStr, Val,11};11};1212cmds/jrsonnet/Cargo.tomldiffbeforeafterboth11workspace = true11workspace = true121213[features]13[features]14default = [15 "exp-regex",16]1718experimental = [14experimental = [19 "exp-preserve-order",15 "exp-preserve-order",crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth5 rc::Rc,5 rc::Rc,6};6};778use jrsonnet_gcmodule::{cc_dyn, Cc, Trace};8use jrsonnet_gcmodule::{cc_dyn, Cc};9use jrsonnet_interner::IBytes;9use jrsonnet_interner::IBytes;10use jrsonnet_parser::{Expr, Spanned};10use jrsonnet_parser::{Expr, Spanned};111112use crate::{function::NativeFn, typed::Typed, Context, Result, Thunk, Val};12use crate::{function::NativeFn, Context, Result, Thunk, Val};131314mod spec;14mod spec;15pub use spec::{ArrayLike, *};15pub use spec::{ArrayLike, *};crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth10use crate::{10use crate::{11 error::ErrorKind::InfiniteRecursionDetected, evaluate, typed::Typed, val::ThunkValue, Context,11 error::ErrorKind::InfiniteRecursionDetected,12 evaluate,13 typed::{IntoUntyped, Typed},14 val::ThunkValue,12 Error, ObjValue, Result, Thunk, Val,15 Context, Error, ObjValue, Result, Thunk, Val,13};16};crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth20 function::{CallLocation, FuncDesc, FuncVal},20 function::{CallLocation, FuncDesc, FuncVal},21 gc::WithCapacityExt as _,21 gc::WithCapacityExt as _,22 in_frame,22 in_frame,23 typed::Typed,23 typed::{FromUntyped, IntoUntyped as _, Typed},24 val::{CachedUnbound, IndexableVal, NumValue, StrValue, Thunk},24 val::{CachedUnbound, IndexableVal, NumValue, StrValue, Thunk},25 with_state, Context, Error, ObjValue, ObjValueBuilder, ObjectAssertion, Pending, Result,25 with_state, Context, Error, ObjValue, ObjValueBuilder, ObjectAssertion, Pending, Result,26 ResultExt, SupThis, Unbound, Val,26 ResultExt, SupThis, Unbound, Val,620 }620 }621 }621 }622 Slice(slice) => {622 Slice(slice) => {623 fn parse_idx<T: Typed>(623 fn parse_idx<T: Typed + FromUntyped>(624 loc: CallLocation<'_>,624 loc: CallLocation<'_>,625 ctx: Context,625 ctx: Context,626 expr: Option<&Spanned<Expr>>,626 expr: Option<&Spanned<Expr>>,crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth8 error::ErrorKind::*,8 error::ErrorKind::*,9 evaluate,9 evaluate,10 stdlib::std_format,10 stdlib::std_format,11 typed::Typed,11 typed::IntoUntyped as _,12 val::{equals, StrValue},12 val::{equals, StrValue},13 Context, Result, Val,13 Context, Result, Val,14};14};crates/jrsonnet-evaluator/src/function/native.rsdiffbeforeafterboth3use jrsonnet_gcmodule::Trace;3use jrsonnet_gcmodule::Trace;445use super::PreparedFuncVal;5use super::PreparedFuncVal;6use crate::{bail, function::FuncVal, typed::Typed, CallLocation, Result, Val};6use crate::{7 function::FuncVal,8 typed::{FromUntyped, IntoUntyped, Typed},9 CallLocation, Result, Val,10};7use jrsonnet_types::{ComplexValType, ValType};11use jrsonnet_types::{ComplexValType, ValType};81212 ($i:expr; $($gen:ident)*) => {16 ($i:expr; $($gen:ident)*) => {13 impl<$($gen,)* O> NativeFn<($($gen,)* O,)>17 impl<$($gen,)* O> NativeFn<($($gen,)* O,)>14 where18 where15 $($gen: Typed,)*19 $($gen: Typed + IntoUntyped,)*16 O: Typed,20 O: Typed + FromUntyped,17 {21 {18 #[allow(non_snake_case, clippy::too_many_arguments)]22 #[allow(non_snake_case, clippy::too_many_arguments)]19 pub fn call(23 pub fn call(22 ) -> Result<O> {26 ) -> Result<O> {23 let val = self.0.call(27 let val = self.0.call(24 CallLocation::native(),28 CallLocation::native(),25 &[$(Typed::into_lazy_untyped($gen),)*],29 &[$(IntoUntyped::into_lazy_untyped($gen),)*],26 &[],30 &[],27 )?;31 )?;28 O::from_untyped(val)32 O::from_untyped(val)29 }33 }30 }34 }31 impl<$($gen,)* O> Typed for NativeFn<($($gen,)* O,)> {35 impl<$($gen,)* O> Typed for NativeFn<($($gen,)* O,)> {32 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);36 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);37 }333834 fn into_untyped(_typed: Self) -> Result<Val> {39 impl<$($gen,)* O> FromUntyped for NativeFn<($($gen,)* O,)> {35 bail!("can only convert functions from jsonnet to native")36 }3738 fn from_untyped(untyped: Val) -> Result<Self> {40 fn from_untyped(untyped: Val) -> Result<Self> {39 let func = FuncVal::from_untyped(untyped)?;41 let func = FuncVal::from_untyped(untyped)?;42 PhantomData,44 PhantomData,43 ))45 ))44 }46 }45 }47 }46 };48 };47 ($i:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {49 ($i:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {48 impl_native_desc!($i; $($cur)*);50 impl_native_desc!($i; $($cur)*);crates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth9use crate::{9use crate::{10 bail,10 bail,11 error::{format_found, suggest_object_fields, ErrorKind::*},11 error::{format_found, suggest_object_fields, ErrorKind::*},12 typed::Typed,12 typed::FromUntyped,13 Error, ObjValue, Result, Val,13 Error, ObjValue, Result, Val,14};14};1515crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth1use std::{collections::BTreeMap, marker::PhantomData, ops::Deref};1use std::{collections::BTreeMap, marker::PhantomData, ops::Deref};223use jrsonnet_gcmodule::{Cc, Trace};3use jrsonnet_gcmodule::Trace;4use jrsonnet_interner::{IBytes, IStr};4use jrsonnet_interner::{IBytes, IStr};5pub use jrsonnet_macros::Typed;5pub use jrsonnet_macros::Typed;6use jrsonnet_types::{ComplexValType, ValType};6use jrsonnet_types::{ComplexValType, ValType};778use crate::{8use crate::{9 arr::{ArrValue, BytesArray},9 arr::{ArrValue, BytesArray},10 bail,10 bail,11 function::{FuncDesc, FuncVal},11 function::FuncVal,12 typed::CheckType,12 typed::CheckType,13 val::{IndexableVal, NumValue, StrValue, ThunkMapper},13 val::{IndexableVal, NumValue, StrValue, ThunkMapper},14 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,14 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,15};15};161617#[derive(Trace)]17#[derive(Trace)]18struct FromUntyped<K: Trace>(PhantomData<fn() -> K>);18struct ThunkFromUntyped<K: Trace>(PhantomData<fn() -> K>);19impl<K> ThunkMapper<Val> for FromUntyped<K>19impl<K> ThunkMapper<Val> for ThunkFromUntyped<K>20where20where21 K: Typed + Trace,21 K: Typed + FromUntyped + Trace,22{22{23 type Output = K;23 type Output = K;242425 fn map(self, from: Val) -> Result<Self::Output> {25 fn map(self, from: Val) -> Result<Self::Output> {26 K::from_untyped(from)26 K::from_untyped(from)27 }27 }28}28}29impl<K: Trace> Default for FromUntyped<K> {29impl<K: Trace> Default for ThunkFromUntyped<K> {30 fn default() -> Self {30 fn default() -> Self {31 Self(PhantomData)31 Self(PhantomData)32 }32 }33}33}34#[derive(Trace)]35struct ThunkIntoUntyped<K: Trace>(PhantomData<fn() -> K>);36impl<K> ThunkMapper<K> for ThunkIntoUntyped<K>37where38 K: Typed + Trace + IntoUntyped,39{40 type Output = Val;4142 fn map(self, from: K) -> Result<Self::Output> {43 K::into_untyped(from)44 }45}46impl<K: Trace> Default for ThunkIntoUntyped<K> {47 fn default() -> Self {48 Self(PhantomData)49 }50}345135pub trait TypedObj: Typed {52pub trait TypedObj: Typed {36 fn serialize(self, out: &mut ObjValueBuilder) -> Result<()>;53 fn serialize(self, out: &mut ObjValueBuilder) -> Result<()>;42 }59 }43}60}446145pub trait Typed: Sized {62pub trait Typed: Sized {46 const TYPE: &'static ComplexValType;63 const TYPE: &'static ComplexValType;64}65pub trait IntoUntyped: Typed {66 // Whatever caller should use `into_lazy_untyped` instead of `into_untyped`67 fn provides_lazy() -> bool {68 false69 }47 fn into_untyped(typed: Self) -> Result<Val>;70 fn into_untyped(typed: Self) -> Result<Val>;48 fn into_lazy_untyped(typed: Self) -> Thunk<Val> {71 fn into_lazy_untyped(typed: Self) -> Thunk<Val> {49 Thunk::from(Self::into_untyped(typed))72 Thunk::from(Self::into_untyped(typed))50 }73 }74}75pub trait IntoUntypedResult: Typed {76 /// Hack to make builtins be able to return non-result values, and make macros able to convert those values to result77 /// This method returns identity in impl Typed for Result, and should not be overriden78 #[doc(hidden)]79 fn into_untyped_result(typed: Self) -> Result<Val>;80}81impl<T> IntoUntypedResult for T82where83 T: IntoUntyped,84{85 fn into_untyped_result(typed: Self) -> Result<Val> {86 T::into_untyped(typed)87 }88}8990pub trait FromUntyped: Typed {51 fn from_untyped(untyped: Val) -> Result<Self>;91 fn from_untyped(untyped: Val) -> Result<Self>;52 fn from_lazy_untyped(lazy: Thunk<Val>) -> Result<Self> {92 fn from_lazy_untyped(lazy: Thunk<Val>) -> Result<Self> {53 Self::from_untyped(lazy.evaluate()?)93 Self::from_untyped(lazy.evaluate()?)54 }94 }5556 // Whatever caller should use `into_lazy_untyped` instead of `into_untyped`57 fn provides_lazy() -> bool {58 false59 }609561 // Whatever caller should use `from_lazy_untyped` instead of `from_untyped` when possible96 // Whatever caller should use `from_lazy_untyped` instead of `from_untyped` when possible62 fn wants_lazy() -> bool {97 fn wants_lazy() -> bool {63 false98 false64 }99 }65100}66 /// Hack to make builtins be able to return non-result values, and make macros able to convert those values to result67 /// This method returns identity in impl Typed for Result, and should not be overriden68 #[doc(hidden)]69 fn into_result(typed: Self) -> Result<Val> {70 let value = Self::into_untyped(typed)?;71 Ok(value)72 }73}7410175impl<T> Typed for Thunk<T>102impl<T> Typed for Thunk<T>76where103where77 T: Typed + Trace + Clone,104 T: Typed + Trace + Clone,78{105{79 const TYPE: &'static ComplexValType = &ComplexValType::Lazy(T::TYPE);106 const TYPE: &'static ComplexValType = &ComplexValType::Lazy(T::TYPE);80107}108109impl<T> IntoUntyped for Thunk<T>110where111 T: Typed + IntoUntyped + Trace + Clone,112{81 fn into_untyped(typed: Self) -> Result<Val> {113 fn into_untyped(typed: Self) -> Result<Val> {82 T::into_untyped(typed.evaluate()?)114 T::into_untyped(typed.evaluate()?)83 }115 }8485 fn from_untyped(untyped: Val) -> Result<Self> {86 Self::from_lazy_untyped(Thunk::evaluated(untyped))87 }8889 fn provides_lazy() -> bool {116 fn provides_lazy() -> bool {90 true117 true91 }118 }9211993 fn into_lazy_untyped(inner: Self) -> Thunk<Val> {120 fn into_lazy_untyped(inner: Self) -> Thunk<Val> {94 #[derive(Trace)]95 struct IntoUntyped<K: Trace>(PhantomData<fn() -> K>);96 impl<K> ThunkMapper<K> for IntoUntyped<K>97 where98 K: Typed + Trace,99 {100 type Output = Val;101102 fn map(self, from: K) -> Result<Self::Output> {103 K::into_untyped(from)104 }105 }106 impl<K: Trace> Default for IntoUntyped<K> {107 fn default() -> Self {108 Self(PhantomData)109 }110 }111 inner.map(<IntoUntyped<T>>::default())121 inner.map(<ThunkIntoUntyped<T>>::default())112 }122 }123}124125impl<T> FromUntyped for Thunk<T>126where127 T: Typed + FromUntyped + Trace + Clone,128{129 fn from_untyped(untyped: Val) -> Result<Self> {130 Self::from_lazy_untyped(Thunk::evaluated(untyped))131 }113132114 fn wants_lazy() -> bool {133 fn wants_lazy() -> bool {115 true134 true116 }135 }117136118 fn from_lazy_untyped(inner: Thunk<Val>) -> Result<Self> {137 fn from_lazy_untyped(inner: Thunk<Val>) -> Result<Self> {119 Ok(inner.map(<FromUntyped<T>>::default()))138 Ok(inner.map(<ThunkFromUntyped<T>>::default()))120 }139 }121}140}122141123pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS)) - 1) as f64;142pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS)) - 1) as f64;124pub const MIN_SAFE_INTEGER: f64 = (-((1i64 << (f64::MANTISSA_DIGITS)) - 1)) as f64;143pub const MIN_SAFE_INTEGER: f64 = (-((1i64 << (f64::MANTISSA_DIGITS)) - 1)) as f64;125144126macro_rules! impl_int {145macro_rules! impl_int {127 ($($ty:ty)*) => {$(146 ($($ty:ty)*) => {$(128 impl Typed for $ty {147 impl Typed for $ty {129 const TYPE: &'static ComplexValType =148 const TYPE: &'static ComplexValType =130 &ComplexValType::BoundedNumber(Some(Self::MIN as f64), Some(Self::MAX as f64));149 &ComplexValType::BoundedNumber(Some(Self::MIN as f64), Some(Self::MAX as f64));150 }151 impl FromUntyped for $ty {131 fn from_untyped(value: Val) -> Result<Self> {152 fn from_untyped(value: Val) -> Result<Self> {132 <Self as Typed>::TYPE.check(&value)?;153 <Self as Typed>::TYPE.check(&value)?;133 match value {154 match value {145 _ => unreachable!(),166 _ => unreachable!(),146 }167 }147 }168 }169 }170 impl IntoUntyped for $ty {148 fn into_untyped(value: Self) -> Result<Val> {171 fn into_untyped(value: Self) -> Result<Val> {149 Ok(Val::Num(value.into()))172 Ok(Val::Num(value.into()))150 }173 }151 }174 }152 )*};175 )*};153}176}154177177 }200 }178 }201 }179202180 impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {203 impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {181 const TYPE: &'static ComplexValType =204 const TYPE: &'static ComplexValType =182 &ComplexValType::BoundedNumber(205 &ComplexValType::BoundedNumber(183 Some(MIN as f64),206 Some(MIN as f64),184 Some(MAX as f64),207 Some(MAX as f64),185 );208 );186209 }210211 impl<const MIN: $ty, const MAX: $ty> FromUntyped for $name<MIN, MAX> {187 fn from_untyped(value: Val) -> Result<Self> {212 fn from_untyped(value: Val) -> Result<Self> {188 <Self as Typed>::TYPE.check(&value)?;213 <Self as Typed>::TYPE.check(&value)?;189 match value {214 match value {201 _ => unreachable!(),226 _ => unreachable!(),202 }227 }203 }228 }204229 }230231 impl<const MIN: $ty, const MAX: $ty> IntoUntyped for $name<MIN, MAX> {205 #[allow(clippy::cast_lossless)]232 #[allow(clippy::cast_lossless)]206 fn into_untyped(value: Self) -> Result<Val> {233 fn into_untyped(value: Self) -> Result<Val> {207 Ok(Val::try_num(value.0)?)234 Ok(Val::try_num(value.0)?)208 }235 }209 }236 }210 )*};237 )*};211}238}212239218 BoundedUsize = usize245 BoundedUsize = usize219);246);220247221impl Typed for f64 {248impl Typed for f64 {222 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);249 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);223250}251impl IntoUntyped for f64 {224 fn into_untyped(value: Self) -> Result<Val> {252 fn into_untyped(value: Self) -> Result<Val> {225 Ok(Val::try_num(value)?)253 Ok(Val::try_num(value)?)226 }254 }227255}256impl FromUntyped for f64 {228 fn from_untyped(value: Val) -> Result<Self> {257 fn from_untyped(value: Val) -> Result<Self> {229 <Self as Typed>::TYPE.check(&value)?;258 <Self as Typed>::TYPE.check(&value)?;230 match value {259 match value {231 Val::Num(n) => Ok(n.get()),260 Val::Num(n) => Ok(n.get()),232 _ => unreachable!(),261 _ => unreachable!(),233 }262 }234 }263 }235}264}236265237pub struct PositiveF64(pub f64);266pub struct PositiveF64(pub f64);238impl Typed for PositiveF64 {267impl Typed for PositiveF64 {239 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(0.0), None);268 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(0.0), None);240269}270impl IntoUntyped for PositiveF64 {241 fn into_untyped(value: Self) -> Result<Val> {271 fn into_untyped(value: Self) -> Result<Val> {242 Ok(Val::try_num(value.0)?)272 Ok(Val::try_num(value.0)?)243 }273 }244274}275impl FromUntyped for PositiveF64 {245 fn from_untyped(value: Val) -> Result<Self> {276 fn from_untyped(value: Val) -> Result<Self> {246 <Self as Typed>::TYPE.check(&value)?;277 <Self as Typed>::TYPE.check(&value)?;247 match value {278 match value {248 Val::Num(n) => Ok(Self(n.get())),279 Val::Num(n) => Ok(Self(n.get())),249 _ => unreachable!(),280 _ => unreachable!(),250 }281 }251 }282 }252}283}253impl Typed for usize {284impl Typed for usize {254 const TYPE: &'static ComplexValType =285 const TYPE: &'static ComplexValType =255 &ComplexValType::BoundedNumber(Some(0.0), Some(MAX_SAFE_INTEGER));286 &ComplexValType::BoundedNumber(Some(0.0), Some(MAX_SAFE_INTEGER));256287}288impl IntoUntyped for usize {257 fn into_untyped(value: Self) -> Result<Val> {289 fn into_untyped(value: Self) -> Result<Val> {258 Ok(Val::try_num(value)?)290 Ok(Val::try_num(value)?)259 }291 }260292}293impl FromUntyped for usize {261 fn from_untyped(value: Val) -> Result<Self> {294 fn from_untyped(value: Val) -> Result<Self> {262 <Self as Typed>::TYPE.check(&value)?;295 <Self as Typed>::TYPE.check(&value)?;263 match value {296 match value {272 _ => unreachable!(),305 _ => unreachable!(),273 }306 }274 }307 }275}308}276309277impl Typed for IStr {310impl Typed for IStr {278 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);311 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);279312}313impl IntoUntyped for IStr {280 fn into_untyped(value: Self) -> Result<Val> {314 fn into_untyped(value: Self) -> Result<Val> {281 Ok(Val::string(value))315 Ok(Val::string(value))282 }316 }283317}318impl FromUntyped for IStr {284 fn from_untyped(value: Val) -> Result<Self> {319 fn from_untyped(value: Val) -> Result<Self> {285 <Self as Typed>::TYPE.check(&value)?;320 <Self as Typed>::TYPE.check(&value)?;286 match value {321 match value {287 Val::Str(s) => Ok(s.into_flat()),322 Val::Str(s) => Ok(s.into_flat()),288 _ => unreachable!(),323 _ => unreachable!(),289 }324 }290 }325 }291}326}292327293impl Typed for String {328impl Typed for String {294 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);329 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);295330}331impl IntoUntyped for String {296 fn into_untyped(value: Self) -> Result<Val> {332 fn into_untyped(value: Self) -> Result<Val> {297 Ok(Val::string(value))333 Ok(Val::string(value))298 }334 }299335}336impl FromUntyped for String {300 fn from_untyped(value: Val) -> Result<Self> {337 fn from_untyped(value: Val) -> Result<Self> {301 <Self as Typed>::TYPE.check(&value)?;338 <Self as Typed>::TYPE.check(&value)?;302 match value {339 match value {303 Val::Str(s) => Ok(s.to_string()),340 Val::Str(s) => Ok(s.to_string()),304 _ => unreachable!(),341 _ => unreachable!(),305 }342 }306 }343 }307}344}308345309impl Typed for StrValue {346impl Typed for StrValue {310 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);347 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);311348}349impl IntoUntyped for StrValue {312 fn into_untyped(value: Self) -> Result<Val> {350 fn into_untyped(value: Self) -> Result<Val> {313 Ok(Val::Str(value))351 Ok(Val::Str(value))314 }352 }315353}354impl FromUntyped for StrValue {316 fn from_untyped(value: Val) -> Result<Self> {355 fn from_untyped(value: Val) -> Result<Self> {317 <Self as Typed>::TYPE.check(&value)?;356 <Self as Typed>::TYPE.check(&value)?;318 match value {357 match value {319 Val::Str(s) => Ok(s),358 Val::Str(s) => Ok(s),320 _ => unreachable!(),359 _ => unreachable!(),321 }360 }322 }361 }323}362}324363325impl Typed for char {364impl Typed for char {326 const TYPE: &'static ComplexValType = &ComplexValType::Char;365 const TYPE: &'static ComplexValType = &ComplexValType::Char;327366}367impl IntoUntyped for char {328 fn into_untyped(value: Self) -> Result<Val> {368 fn into_untyped(value: Self) -> Result<Val> {329 Ok(Val::string(value))369 Ok(Val::string(value))330 }370 }331371}372impl FromUntyped for char {332 fn from_untyped(value: Val) -> Result<Self> {373 fn from_untyped(value: Val) -> Result<Self> {333 <Self as Typed>::TYPE.check(&value)?;374 <Self as Typed>::TYPE.check(&value)?;334 match value {375 match value {335 Val::Str(s) => Ok(s.into_flat().chars().next().unwrap()),376 Val::Str(s) => Ok(s.into_flat().chars().next().unwrap()),336 _ => unreachable!(),377 _ => unreachable!(),337 }378 }338 }379 }339}380}340381382// TODO: View into vec using ArrayLike?341impl<T> Typed for Vec<T>383impl<T> Typed for Vec<T>342where384where343 T: Typed,385 T: Typed,344{386{345 const TYPE: &'static ComplexValType = &ComplexValType::ArrayRef(T::TYPE);387 const TYPE: &'static ComplexValType = &ComplexValType::ArrayRef(T::TYPE);346388}389impl<T: Typed + IntoUntyped> IntoUntyped for Vec<T> {347 fn into_untyped(value: Self) -> Result<Val> {390 fn into_untyped(value: Self) -> Result<Val> {348 Ok(Val::Arr(391 Ok(Val::Arr(349 value392 value352 .collect::<Result<ArrValue>>()?,395 .collect::<Result<ArrValue>>()?,353 ))396 ))354 }397 }355398}399impl<T: Typed + FromUntyped> FromUntyped for Vec<T> {356 fn from_untyped(value: Val) -> Result<Self> {400 fn from_untyped(value: Val) -> Result<Self> {357 let Val::Arr(a) = value else {401 let Val::Arr(a) = value else {358 <Self as Typed>::TYPE.check(&value)?;402 <Self as Typed>::TYPE.check(&value)?;367 })411 })368 .collect::<Result<Self>>()412 .collect::<Result<Self>>()369 }413 }370}414}371415416// TODO: View into BTreeMap using ObjectCore?372impl<K: Typed + Ord, V: Typed> Typed for BTreeMap<K, V> {417impl<K, V> Typed for BTreeMap<K, V>418where419 K: Typed + Ord,420 V: Typed,421{373 const TYPE: &'static ComplexValType = &ComplexValType::AttrsOf(V::TYPE);422 const TYPE: &'static ComplexValType = &ComplexValType::AttrsOf(V::TYPE);374423}424impl<K, V> IntoUntyped for BTreeMap<K, V>425where426 K: Typed + Ord + IntoUntyped,427 V: Typed + IntoUntyped,428{375 fn into_untyped(typed: Self) -> Result<Val> {429 fn into_untyped(typed: Self) -> Result<Val> {376 let mut out = ObjValueBuilder::with_capacity(typed.len());430 let mut out = ObjValueBuilder::with_capacity(typed.len());377 for (k, v) in typed {431 for (k, v) in typed {383 }437 }384 Ok(Val::Obj(out.build()))438 Ok(Val::Obj(out.build()))385 }439 }386440}441impl<K, V> FromUntyped for BTreeMap<K, V>442where443 K: FromUntyped + Ord,444 V: FromUntyped,445{387 fn from_untyped(value: Val) -> Result<Self> {446 fn from_untyped(value: Val) -> Result<Self> {388 Self::TYPE.check(&value)?;447 Self::TYPE.check(&value)?;389 let obj = value.as_obj().expect("typecheck should fail");448 let obj = value.as_obj().expect("typecheck should fail");412 }471 }413 Ok(out)472 Ok(out)414 }473 }415}474}416475417impl Typed for Val {476impl Typed for Val {418 const TYPE: &'static ComplexValType = &ComplexValType::Any;477 const TYPE: &'static ComplexValType = &ComplexValType::Any;419478}479impl IntoUntyped for Val {420 fn into_untyped(typed: Self) -> Result<Val> {480 fn into_untyped(typed: Self) -> Result<Val> {421 Ok(typed)481 Ok(typed)422 }482 }483}484impl FromUntyped for Val {423 fn from_untyped(untyped: Val) -> Result<Self> {485 fn from_untyped(untyped: Val) -> Result<Self> {424 Ok(untyped)486 Ok(untyped)425 }487 }426}488}427489428// Hack429#[doc(hidden)]490#[doc(hidden)]430impl<T> Typed for Result<T>491impl<T> Typed for Result<T>431where492where432 T: Typed,493 T: Typed,433{494{434 const TYPE: &'static ComplexValType = &ComplexValType::Any;495 const TYPE: &'static ComplexValType = &ComplexValType::Any;435496}436 fn into_untyped(_typed: Self) -> Result<Val> {497impl<T: IntoUntyped> IntoUntypedResult for Result<T> {437 panic!("do not use this conversion")438 }439440 fn from_untyped(_untyped: Val) -> Result<Self> {441 panic!("do not use this conversion")442 }443444 fn into_result(typed: Self) -> Result<Val> {498 fn into_untyped_result(typed: Self) -> Result<Val> {445 typed.map(T::into_untyped)?499 typed.map(T::into_untyped)?446 }500 }447}501}448502449/// Specialization503/// Specialization450impl Typed for IBytes {504impl Typed for IBytes {451 const TYPE: &'static ComplexValType =505 const TYPE: &'static ComplexValType =452 &ComplexValType::ArrayRef(&ComplexValType::BoundedNumber(Some(0.0), Some(255.0)));506 &ComplexValType::ArrayRef(&ComplexValType::BoundedNumber(Some(0.0), Some(255.0)));453507}508impl IntoUntyped for IBytes {454 fn into_untyped(value: Self) -> Result<Val> {509 fn into_untyped(value: Self) -> Result<Val> {455 Ok(Val::Arr(ArrValue::bytes(value)))510 Ok(Val::Arr(ArrValue::bytes(value)))456 }511 }457512}513impl FromUntyped for IBytes {458 fn from_untyped(value: Val) -> Result<Self> {514 fn from_untyped(value: Val) -> Result<Self> {459 let Val::Arr(a) = &value else {515 let Val::Arr(a) = &value else {460 <Self as Typed>::TYPE.check(&value)?;516 <Self as Typed>::TYPE.check(&value)?;472 }528 }473 Ok(out.as_slice().into())529 Ok(out.as_slice().into())474 }530 }475}531}476532477pub struct M1;533pub struct M1;478impl Typed for M1 {534impl Typed for M1 {479 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(-1.0), Some(-1.0));535 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(-1.0), Some(-1.0));480536}537impl IntoUntyped for M1 {481 fn into_untyped(_: Self) -> Result<Val> {538 fn into_untyped(_: Self) -> Result<Val> {482 Ok(Val::Num(NumValue::new(-1.0).expect("finite")))539 Ok(Val::Num(NumValue::new(-1.0).expect("finite")))483 }540 }484541}542impl FromUntyped for M1 {485 fn from_untyped(value: Val) -> Result<Self> {543 fn from_untyped(value: Val) -> Result<Self> {486 <Self as Typed>::TYPE.check(&value)?;544 <Self as Typed>::TYPE.check(&value)?;487 Ok(Self)545 Ok(Self)488 }546 }489}547}490548491macro_rules! decl_either {549macro_rules! decl_either {492 ($($name: ident, $($id: ident)*);*) => {$(550 ($($name: ident, $($id: ident)*);*) => {$(497 impl<$($id),*> Typed for $name<$($id),*>555 impl<$($id),*> Typed for $name<$($id),*>498 where556 where499 $($id: Typed,)*557 $($id: Typed,)*500 {558 {501 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[$($id::TYPE),*]);559 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[$($id::TYPE),*]);502560 }561 impl<$($id),*> IntoUntyped for $name<$($id),*>562 where563 $($id: Typed + IntoUntyped,)*564 {503 fn into_untyped(value: Self) -> Result<Val> {565 fn into_untyped(value: Self) -> Result<Val> {504 match value {$(566 match value {$(505 $name::$id(v) => $id::into_untyped(v)567 $name::$id(v) => $id::into_untyped(v)506 ),*}568 ),*}507 }569 }508570 }571572 impl<$($id),*> FromUntyped for $name<$($id),*>573 where574 $($id: Typed + FromUntyped,)*575 {509 fn from_untyped(value: Val) -> Result<Self> {576 fn from_untyped(value: Val) -> Result<Self> {510 $(577 $(511 if $id::TYPE.check(&value).is_ok() {578 if $id::TYPE.check(&value).is_ok() {516 unreachable!()583 unreachable!()517 }584 }518 }585 }519 }586 }520 )*}587 )*}521}588}522decl_either!(589decl_either!(542609543pub type MyType = Either![u32, f64, String];610pub type MyType = Either![u32, f64, String];544611545impl Typed for ArrValue {612impl Typed for ArrValue {546 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);613 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);547614}615impl IntoUntyped for ArrValue {548 fn into_untyped(value: Self) -> Result<Val> {616 fn into_untyped(value: Self) -> Result<Val> {549 Ok(Val::Arr(value))617 Ok(Val::Arr(value))550 }618 }551619}620impl FromUntyped for ArrValue {552 fn from_untyped(value: Val) -> Result<Self> {621 fn from_untyped(value: Val) -> Result<Self> {553 <Self as Typed>::TYPE.check(&value)?;622 <Self as Typed>::TYPE.check(&value)?;554 match value {623 match value {555 Val::Arr(a) => Ok(a),624 Val::Arr(a) => Ok(a),556 _ => unreachable!(),625 _ => unreachable!(),557 }626 }558 }627 }559}628}560629561impl Typed for FuncVal {630impl Typed for FuncVal {562 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);631 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);563632}633impl IntoUntyped for FuncVal {564 fn into_untyped(value: Self) -> Result<Val> {634 fn into_untyped(value: Self) -> Result<Val> {565 Ok(Val::Func(value))635 Ok(Val::Func(value))566 }636 }567637}638impl FromUntyped for FuncVal {568 fn from_untyped(value: Val) -> Result<Self> {639 fn from_untyped(value: Val) -> Result<Self> {569 <Self as Typed>::TYPE.check(&value)?;640 <Self as Typed>::TYPE.check(&value)?;570 match value {641 match value {571 Val::Func(a) => Ok(a),642 Val::Func(a) => Ok(a),572 _ => unreachable!(),643 _ => unreachable!(),573 }644 }574 }645 }575}646}576647577impl Typed for Cc<FuncDesc> {648impl Typed for ObjValue {578 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);649 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Obj);579580 fn into_untyped(value: Self) -> Result<Val> {581 Ok(Val::Func(FuncVal::Normal(value)))582 }583584 fn from_untyped(value: Val) -> Result<Self> {585 <Self as Typed>::TYPE.check(&value)?;586 match value {587 Val::Func(FuncVal::Normal(desc)) => Ok(desc),588 Val::Func(_) => bail!("expected normal function, not builtin"),589 _ => unreachable!(),590 }591 }592}650}593594impl Typed for ObjValue {651impl IntoUntyped for ObjValue {595 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Obj);596597 fn into_untyped(value: Self) -> Result<Val> {652 fn into_untyped(value: Self) -> Result<Val> {598 Ok(Val::Obj(value))653 Ok(Val::Obj(value))599 }654 }600655}656impl FromUntyped for ObjValue {601 fn from_untyped(value: Val) -> Result<Self> {657 fn from_untyped(value: Val) -> Result<Self> {602 <Self as Typed>::TYPE.check(&value)?;658 <Self as Typed>::TYPE.check(&value)?;603 match value {659 match value {604 Val::Obj(a) => Ok(a),660 Val::Obj(a) => Ok(a),605 _ => unreachable!(),661 _ => unreachable!(),606 }662 }607 }663 }608}664}609665610impl Typed for bool {666impl Typed for bool {611 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Bool);667 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Bool);612668}669impl IntoUntyped for bool {613 fn into_untyped(value: Self) -> Result<Val> {670 fn into_untyped(value: Self) -> Result<Val> {614 Ok(Val::Bool(value))671 Ok(Val::Bool(value))615 }672 }616673}674impl FromUntyped for bool {617 fn from_untyped(value: Val) -> Result<Self> {675 fn from_untyped(value: Val) -> Result<Self> {618 <Self as Typed>::TYPE.check(&value)?;676 <Self as Typed>::TYPE.check(&value)?;619 match value {677 match value {620 Val::Bool(a) => Ok(a),678 Val::Bool(a) => Ok(a),621 _ => unreachable!(),679 _ => unreachable!(),622 }680 }623 }681 }624}682}683625impl Typed for IndexableVal {684impl Typed for IndexableVal {626 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[685 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[627 &ComplexValType::Simple(ValType::Arr),686 &ComplexValType::Simple(ValType::Arr),628 &ComplexValType::Simple(ValType::Str),687 &ComplexValType::Simple(ValType::Str),629 ]);688 ]);630689}690impl IntoUntyped for IndexableVal {631 fn into_untyped(value: Self) -> Result<Val> {691 fn into_untyped(value: Self) -> Result<Val> {632 match value {692 match value {633 Self::Str(s) => Ok(Val::string(s)),693 Self::Str(s) => Ok(Val::string(s)),634 Self::Arr(a) => Ok(Val::Arr(a)),694 Self::Arr(a) => Ok(Val::Arr(a)),635 }695 }636 }696 }637697}698impl FromUntyped for IndexableVal {638 fn from_untyped(value: Val) -> Result<Self> {699 fn from_untyped(value: Val) -> Result<Self> {639 <Self as Typed>::TYPE.check(&value)?;700 <Self as Typed>::TYPE.check(&value)?;640 value.into_indexable()701 value.into_indexable()641 }702 }642}703}643704644pub struct Null;705pub struct Null;645impl Typed for Null {706impl Typed for Null {646 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Null);707 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Null);647708}709impl IntoUntyped for Null {648 fn into_untyped(_: Self) -> Result<Val> {710 fn into_untyped(_: Self) -> Result<Val> {649 Ok(Val::Null)711 Ok(Val::Null)650 }712 }651713}714impl FromUntyped for Null {652 fn from_untyped(value: Val) -> Result<Self> {715 fn from_untyped(value: Val) -> Result<Self> {653 <Self as Typed>::TYPE.check(&value)?;716 <Self as Typed>::TYPE.check(&value)?;654 Ok(Self)717 Ok(Self)655 }718 }656}719}657720658impl<T> Typed for Option<T>721impl<T> Typed for Option<T>659where722where660 T: Typed,723 T: Typed,661{724{662 const TYPE: &'static ComplexValType =725 const TYPE: &'static ComplexValType =663 &ComplexValType::UnionRef(&[&ComplexValType::Simple(ValType::Null), T::TYPE]);726 &ComplexValType::UnionRef(&[&ComplexValType::Simple(ValType::Null), T::TYPE]);664727}728impl<T> IntoUntyped for Option<T>729where730 T: Typed + IntoUntyped,731{665 fn into_untyped(typed: Self) -> Result<Val> {732 fn into_untyped(typed: Self) -> Result<Val> {666 typed.map_or_else(|| Ok(Val::Null), |v| T::into_untyped(v))733 typed.map_or_else(|| Ok(Val::Null), |v| T::into_untyped(v))667 }734 }668735}736impl<T> FromUntyped for Option<T>737where738 T: Typed + FromUntyped,739{669 fn from_untyped(untyped: Val) -> Result<Self> {740 fn from_untyped(untyped: Val) -> Result<Self> {670 if matches!(untyped, Val::Null) {741 if matches!(untyped, Val::Null) {671 Ok(None)742 Ok(None)672 } else {743 } else {673 T::from_untyped(untyped).map(Some)744 T::from_untyped(untyped).map(Some)674 }745 }675 }746 }676}747}677748678impl Typed for NumValue {749impl Typed for NumValue {679 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);750 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);680751}752impl IntoUntyped for NumValue {681 fn into_untyped(typed: Self) -> Result<Val> {753 fn into_untyped(typed: Self) -> Result<Val> {682 Ok(Val::Num(typed))754 Ok(Val::Num(typed))683 }755 }684756}757impl FromUntyped for NumValue {685 fn from_untyped(untyped: Val) -> Result<Self> {758 fn from_untyped(untyped: Val) -> Result<Self> {686 Self::TYPE.check(&untyped)?;759 Self::TYPE.check(&untyped)?;687 match untyped {760 match untyped {688 Val::Num(v) => Ok(v),761 Val::Num(v) => Ok(v),689 _ => unreachable!(),762 _ => unreachable!(),690 }763 }691 }764 }692}765}693766crates/jrsonnet-interner/src/names.rsdiffbeforeafterbothno syntactic changes
crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth8 parse_macro_input,8 parse_macro_input,9 punctuated::Punctuated,9 punctuated::Punctuated,10 spanned::Spanned,10 spanned::Spanned,11 token::{self, Comma},11 token::Comma,12 Attribute, DeriveInput, Error, Expr, ExprClosure, FnArg, GenericArgument, Ident, ItemFn,12 Attribute, DeriveInput, Error, Expr, ExprClosure, FnArg, GenericArgument, Ident, ItemFn,13 LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type,13 LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type,14};14};151516use self::typed::derive_typed_inner;16use self::typed::derive_typed_inner;171718mod typed;18mod names;19mod names;19mod typed;202021fn try_parse_attr_noargs<I>(attrs: &[Attribute], ident: I) -> Result<bool>21fn try_parse_attr_noargs<I>(attrs: &[Attribute], ident: I) -> Result<bool>22where22where202 _ => {}202 _ => {}203 }203 }204204205 let (optionality, ty) = if try_parse_attr_noargs(&mut arg.attrs, "default")? {205 let (optionality, ty) = if try_parse_attr_noargs(&arg.attrs, "default")? {206 remove_attr(&mut arg.attrs, "default");206 remove_attr(&mut arg.attrs, "default");207 (Optionality::TypeDefault, ty.clone())207 (Optionality::TypeDefault, ty.clone())208 } else if let Some(default) = parse_attr::<_, _>(&arg.attrs, "default")? {208 } else if let Some(default) = parse_attr::<_, _>(&arg.attrs, "default")? {322 let name = name.as_ref().map_or("<unnamed>", String::as_str);322 let name = name.as_ref().map_or("<unnamed>", String::as_str);323 let eval = quote! {jrsonnet_evaluator::in_description_frame(323 let eval = quote! {jrsonnet_evaluator::in_description_frame(324 || format!("argument <{}> evaluation", #name),324 || format!("argument <{}> evaluation", #name),325 || <#ty>::from_untyped(value.evaluate()?),325 || <#ty as FromUntyped>::from_untyped(value.evaluate()?),326 )?};326 )?};327 let value = match optionality {327 let value = match optionality {328 Optionality::Required => quote! {{328 Optionality::Required => quote! {{411 use ::jrsonnet_evaluator::{411 use ::jrsonnet_evaluator::{412 State, Val,412 State, Val,413 function::{builtin::{Builtin, StaticBuiltin}, FunctionSignature, ParamParse, ParamName, ParamDefault, CallLocation},413 function::{builtin::{Builtin, StaticBuiltin}, FunctionSignature, ParamParse, ParamName, ParamDefault, CallLocation},414 Result, Context, typed::Typed,414 Result, Context, typed::{Typed, FromUntyped, IntoUntypedResult},415 parser::Span, params, Thunk,415 parser::Span, params, Thunk,416 };416 };417 params!(417 params!(432 #[allow(unused_variables)]432 #[allow(unused_variables)]433 fn call(&self, location: CallLocation<'_>, parsed: &[Option<Thunk<Val>>]) -> Result<Val> {433 fn call(&self, location: CallLocation<'_>, parsed: &[Option<Thunk<Val>>]) -> Result<Val> {434 let result: #result = #name(#(#pass)*);434 let result: #result = #name(#(#pass)*);435 <_ as Typed>::into_result(result)435 <_ as IntoUntypedResult>::into_untyped_result(result)436 }436 }437 fn as_any(&self) -> &dyn ::std::any::Any {437 fn as_any(&self) -> &dyn ::std::any::Any {438 self438 selfcrates/jrsonnet-macros/src/names.rsdiffbeforeafterboth1use proc_macro2::TokenStream;1use proc_macro2::TokenStream;2use quote::quote;2use quote::quote;3use std::cell::RefCell;435#[derive(Default)]4#[derive(Default)]6pub struct Names {5pub struct Names {crates/jrsonnet-macros/src/typed.rsdiffbeforeafterboth178 None178 None179 };179 };180180181 __value.map(<#ty as Typed>::from_untyped).transpose()?181 __value.map(<#ty as FromUntyped>::from_untyped).transpose()?182 },182 },183 }183 }184 }184 }219 return Err(ErrorKind::NoSuchField(__names[#error_text].clone(), vec![]).into());219 return Err(ErrorKind::NoSuchField(__names[#error_text].clone(), vec![]).into());220 };220 };221221222 <#ty as Typed>::from_untyped(__value)?222 <#ty as FromUntyped>::from_untyped(__value)?223 },223 },224 }224 }225 }225 }258 out.field(__names[#name].clone())258 out.field(__names[#name].clone())259 #hide259 #hide260 #add260 #add261 .try_thunk(<#ty as Typed>::into_lazy_untyped(value))?;261 .try_thunk(<#ty as IntoUntyped>::into_lazy_untyped(value))?;262 }262 }263 } else {263 } else {264 quote! {264 quote! {265 out.field(__names[#name].clone())265 out.field(__names[#name].clone())266 #hide266 #hide267 #add267 #add268 .try_value(<#ty as Typed>::into_untyped(value)?)?;268 .try_value(<#ty as IntoUntyped>::into_untyped(value)?)?;269 }269 }270 };270 };271 if self.is_option {271 if self.is_option {309 .filter_map(TypedField::expand_field)309 .filter_map(TypedField::expand_field)310 .collect::<Vec<_>>();310 .collect::<Vec<_>>();311 quote! {311 quote! {312 impl #impl_generics Typed for #ident #ty_generics #where_clause {312 impl #impl_generics Typed for #ident #ty_generics #where_clause {313 const TYPE: &'static ComplexValType = &ComplexValType::ObjectRef(&[313 const TYPE: &'static ComplexValType = &ComplexValType::ObjectRef(&[314 #(#fields,)*314 #(#fields,)*315 ]);315 ]);316316 }317318 impl #impl_generics FromUntyped for #ident #ty_generics #where_clause {317 fn from_untyped(value: Val) -> JrResult<Self> {319 fn from_untyped(value: Val) -> JrResult<Self> {318 let obj = value.as_obj().expect("shape is correct");320 let obj = value.as_obj().expect("shape is correct");319 Self::parse(&obj)321 Self::parse(&obj)320 }322 }321323 }324325 impl #impl_generics IntoUntyped for #ident #ty_generics #where_clause {322 fn into_untyped(value: Self) -> JrResult<Val> {326 fn into_untyped(value: Self) -> JrResult<Val> {323 let mut out = ObjValueBuilder::with_capacity(#capacity);327 let mut out = ObjValueBuilder::with_capacity(#capacity);324 value.serialize(&mut out)?;328 value.serialize(&mut out)?;325 Ok(Val::Obj(out.build()))329 Ok(Val::Obj(out.build()))326 }330 }327331 }328 }329 }332 }330 };333 };331334344 Ok(quote! {347 Ok(quote! {345 const _: () = {348 const _: () = {346 use ::jrsonnet_evaluator::{349 use ::jrsonnet_evaluator::{347 typed::{ComplexValType, Typed, TypedObj, CheckType},350 typed::{ComplexValType, Typed, IntoUntyped, FromUntyped, TypedObj, CheckType},348 Val, State,351 Val, State,349 error::{ErrorKind, Result as JrResult},352 error::{ErrorKind, Result as JrResult},350 ObjValueBuilder, ObjValue, IStr,353 ObjValueBuilder, ObjValue, IStr,crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth4 bail,4 bail,5 function::{builtin, FuncVal, NativeFn},5 function::{builtin, FuncVal, NativeFn},6 runtime_error,6 runtime_error,7 typed::{BoundedI32, BoundedUsize, Either2, Typed},7 typed::{BoundedI32, BoundedUsize, Either2, FromUntyped},8 val::{equals, ArrValue, IndexableVal},8 val::{equals, ArrValue, IndexableVal},9 Either, IStr, ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,9 Either, IStr, ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,10};10};24 }24 }25 func.evaluate_trivial().map_or_else(25 func.evaluate_trivial().map_or_else(26 // TODO: Different mapped array impl avoiding allocating unnecessary vals26 // TODO: Different mapped array impl avoiding allocating unnecessary vals27 || Ok(ArrValue::range_exclusive(0, *sz).map(Typed::from_untyped(Val::Func(func))?)),27 || Ok(ArrValue::range_exclusive(0, *sz).map(FromUntyped::from_untyped(Val::Func(func))?)),28 |trivial| {28 |trivial| {29 let mut out = Vec::with_capacity(*sz as usize);29 let mut out = Vec::with_capacity(*sz as usize);30 for _ in 0..*sz {30 for _ in 0..*sz {crates/jrsonnet-stdlib/src/keyf.rsdiffbeforeafterboth1use jrsonnet_evaluator::function::{CallLocation, FuncVal, PreparedFuncVal};1use jrsonnet_evaluator::function::{CallLocation, FuncVal, PreparedFuncVal};2use jrsonnet_evaluator::typed::{ComplexValType, Typed, ValType};2use jrsonnet_evaluator::typed::{ComplexValType, FromUntyped, Typed, ValType};3use jrsonnet_evaluator::{Error, Result, Thunk, Val};3use jrsonnet_evaluator::{Error, Result, Thunk, Val};445#[derive(Default, Clone)]5#[derive(Default, Clone)]29 }29 }30}30}313132impl Typed for KeyF {32impl Typed for KeyF {33 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);33 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);34}35impl FromUntyped for KeyF {34 fn from_untyped(untyped: Val) -> Result<Self> {36 fn from_untyped(untyped: Val) -> Result<Self> {35 FuncVal::from_untyped(untyped).map(Self::new)37 FuncVal::from_untyped(untyped).map(Self::new)36 }38 }3739}38 fn into_untyped(_typed: Self) -> Result<Val> {39 unreachable!("unused, todo: port split of Typed trait from #193")40 }41}4240crates/jrsonnet-stdlib/src/manifest/ini.rsdiffbeforeafterboth223use jrsonnet_evaluator::{3use jrsonnet_evaluator::{4 manifest::{ManifestFormat, ToStringFormat},4 manifest::{ManifestFormat, ToStringFormat},5 typed::Typed,5 typed::{FromUntyped, Typed},6 ObjValue, Result, ResultExt, Val,6 ObjValue, Result, ResultExt, Val,7};7};8use jrsonnet_parser::IStr;8use jrsonnet_parser::IStr;crates/jrsonnet-stdlib/src/manifest/xml.rsdiffbeforeafterboth1use jrsonnet_evaluator::{1use jrsonnet_evaluator::{2 bail, in_description_frame,2 bail, in_description_frame,3 manifest::{ManifestFormat, ToStringFormat},3 manifest::{ManifestFormat, ToStringFormat},4 typed::{ComplexValType, Either2, Typed, ValType},4 typed::{ComplexValType, Either2, FromUntyped, Typed, ValType},5 val::ArrValue,5 val::ArrValue,6 Either, ObjValue, Result, ResultExt, Val,6 Either, ObjValue, Result, ResultExt, Val,7};7};30 },30 },31 String(String),31 String(String),32}32}33impl Typed for JSONMLValue {34 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);35}33impl Typed for JSONMLValue {36impl FromUntyped for JSONMLValue {34 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);3536 fn into_untyped(_typed: Self) -> Result<Val> {37 unreachable!("not used, reserved for parseXML?")38 }3940 fn from_untyped(untyped: Val) -> Result<Self> {37 fn from_untyped(untyped: Val) -> Result<Self> {41 let val = <Either![ArrValue, String]>::from_untyped(untyped)38 let val = <Either![ArrValue, String]>::from_untyped(untyped)73 children: in_description_frame(70 children: in_description_frame(74 || "parsing children".to_owned(),71 || "parsing children".to_owned(),75 || {72 || {76 Typed::from_untyped(Val::Arr(arr.slice(73 FromUntyped::from_untyped(Val::Arr(arr.slice(77 Some(if has_attrs { 2 } else { 1 }),74 Some(if has_attrs { 2 } else { 1 }),78 None,75 None,79 None,76 None,crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth4 bail,4 bail,5 error::{ErrorKind::*, Result},5 error::{ErrorKind::*, Result},6 function::builtin,6 function::builtin,7 typed::{Either2, Typed, M1},7 typed::{Either2, FromUntyped, M1},8 val::{ArrValue, IndexableVal},8 val::{ArrValue, IndexableVal},9 Either, IStr, Val,9 Either, IStr, Val,10};10};tests/tests/builtin.rsdiffbeforeafterboth5 function::{CallLocation, FuncVal, builtin, builtin::Builtin},5 function::{CallLocation, FuncVal, builtin, builtin::Builtin},6 parser::Source,6 parser::Source,7 trace::PathResolver,7 trace::PathResolver,8 typed::Typed,8 typed::FromUntyped,9};9};10use jrsonnet_gcmodule::Trace;10use jrsonnet_gcmodule::Trace;11use jrsonnet_stdlib::ContextInitializer as StdContextInitializer;11use jrsonnet_stdlib::ContextInitializer as StdContextInitializer;tests/tests/typed_obj.rsdiffbeforeafterboth5use jrsonnet_evaluator::{Result, State, trace::PathResolver, typed::Typed};5use jrsonnet_evaluator::{6 Result, State,7 trace::PathResolver,8 typed::{FromUntyped, IntoUntyped, Typed},9};6use jrsonnet_stdlib::ContextInitializer;10use jrsonnet_stdlib::ContextInitializer;71111 b: u16,15 b: u16,12}16}131714fn test_roundtrip<T: Typed + PartialEq + Debug + Clone>(value: T) -> Result<()> {18fn test_roundtrip<T: Typed + PartialEq + Debug + Clone + FromUntyped + IntoUntyped>(19 value: T,20) -> Result<()> {15 let untyped = T::into_untyped(value.clone())?;21 let untyped = T::into_untyped(value.clone())?;