difftreelog
feat exp-bigint
in: master
16 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -298,6 +298,7 @@
"jrsonnet-macros",
"jrsonnet-parser",
"jrsonnet-types",
+ "num-bigint",
"pathdiff",
"rustc-hash",
"serde",
@@ -370,6 +371,7 @@
"jrsonnet-macros",
"jrsonnet-parser",
"md5",
+ "num-bigint",
"serde",
"serde_json",
"serde_yaml_with_quirks",
@@ -449,6 +451,37 @@
]
[[package]]
+name = "num-bigint"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+ "serde",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[workspace]
-package.version = "0.5.0"
+package.version = "0.5.0-pre7"
members = ["crates/*", "bindings/jsonnet", "cmds/jrsonnet", "tests"]
default-members = ["cmds/jrsonnet"]
cmds/jrsonnet/Cargo.tomldiffbeforeafterboth--- a/cmds/jrsonnet/Cargo.toml
+++ b/cmds/jrsonnet/Cargo.toml
@@ -19,6 +19,8 @@
exp-destruct = ["jrsonnet-evaluator/exp-destruct"]
# Iteration over objects yields [key, value] elements
exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]
+# Bigint type
+exp-bigint = ["jrsonnet-evaluator/exp-bigint", "jrsonnet-cli/exp-bigint"]
# std.thisFile support
legacy-this-file = ["jrsonnet-cli/legacy-this-file"]
crates/jrsonnet-cli/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-cli/Cargo.toml
+++ b/crates/jrsonnet-cli/Cargo.toml
@@ -11,6 +11,10 @@
"jrsonnet-evaluator/exp-preserve-order",
"jrsonnet-stdlib/exp-preserve-order",
]
+exp-bigint = [
+ "jrsonnet-evaluator/exp-bigint",
+ "jrsonnet-stdlib/exp-bigint",
+]
legacy-this-file = ["jrsonnet-stdlib/legacy-this-file"]
[dependencies]
crates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-evaluator/Cargo.toml
+++ b/crates/jrsonnet-evaluator/Cargo.toml
@@ -24,6 +24,8 @@
exp-destruct = ["jrsonnet-parser/exp-destruct"]
# Iteration over objects yields [key, value] elements
exp-object-iteration = []
+# Bigint type
+exp-bigint = ["num-bigint"]
# Improves performance, and implements some useful things using nightly-only features
nightly = ["hashbrown/nightly"]
@@ -54,3 +56,5 @@
annotate-snippets = { version = "0.9.1", features = ["color"], optional = true }
# Async imports
async-trait = { version = "0.1.60", optional = true }
+# Bigint
+num-bigint = { version = "0.4.3", features = ["serde"], optional = true }
crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -47,6 +47,8 @@
(Arr(a), Arr(b)) => Val::Arr(ArrValue::extended(a.clone(), b.clone())),
(Num(v1), Num(v2)) => Val::new_checked_num(v1 + v2)?,
+ #[cfg(feature = "exp-bigint")]
+ (BigInt(a), BigInt(b)) => BigInt(Box::new((&**a).clone() + (&**b).clone())),
_ => throw!(BinaryOperatorDoesNotOperateOnValues(
BinaryOpType::Add,
a.value_type(),
@@ -95,6 +97,8 @@
Ok(match (a, b) {
(Str(a), Str(b)) => a.cmp(b),
(Num(a), Num(b)) => a.partial_cmp(b).expect("jsonnet numbers are non NaN"),
+ #[cfg(feature = "exp-bigint")]
+ (BigInt(a), BigInt(b)) => a.cmp(b),
(Arr(a), Arr(b)) => {
if let (Some(ai), Some(bi)) = (a.iter_cheap(), b.iter_cheap()) {
for (a, b) in ai.zip(bi) {
@@ -174,6 +178,12 @@
Num(f64::from((*v1 as i32) >> (*v2 as i32)))
}
+ // Bigint X Bigint
+ #[cfg(feature = "exp-bigint")]
+ (BigInt(a), Mul, BigInt(b)) => BigInt(Box::new((&**a).clone() * (&**b).clone())),
+ #[cfg(feature = "exp-bigint")]
+ (BigInt(a), Sub, BigInt(b)) => BigInt(Box::new((&**a).clone() - (&**b).clone())),
+
_ => throw!(BinaryOperatorDoesNotOperateOnValues(
op,
a.value_type(),
crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth1use std::borrow::Cow;23use jrsonnet_interner::IStr;4use serde::{5 de::Visitor,6 ser::{7 Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,8 SerializeTupleStruct, SerializeTupleVariant,9 },10 Deserialize, Serialize, Serializer,11};1213use crate::{14 arr::ArrValue,15 error::{Error as JrError, ErrorKind, Result},16 val::StrValue,17 ObjValue, ObjValueBuilder, State, Val,18};1920impl<'de> Deserialize<'de> for Val {21 fn deserialize<D>(deserializer: D) -> Result<Val, D::Error>22 where23 D: serde::Deserializer<'de>,24 {25 struct ValVisitor;2627 // macro_rules! visit_num {28 // ($($method:ident => $ty:ty),* $(,)?) => {$(29 // fn $method<E>(self, v: $ty) -> Result<Self::Value, E>30 // where31 // E: serde::de::Error,32 // {33 // Ok(Val::Num(f64::from(v)))34 // }35 // )*};36 // }3738 impl<'de> Visitor<'de> for ValVisitor {39 type Value = Val;4041 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>42 where43 E: serde::de::Error,44 {45 Ok(Val::Bool(v))46 }47 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>48 where49 E: serde::de::Error,50 {51 if !v.is_finite() {52 return Err(E::custom("only finite numbers are supported"));53 }54 Ok(Val::Num(v))55 }56 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>57 where58 E: serde::de::Error,59 {60 Ok(Val::Str(StrValue::Flat(v.into())))61 }6263 // visit_num! {64 // visit_i8 => i8,65 // visit_i16 => i16,66 // visit_i32 => i32,67 // visit_u8 => u8,68 // visit_u16 => u16,69 // visit_u32 => u32,70 // }71 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>72 where73 E: serde::de::Error,74 {75 Ok(Val::Num(v as f64))76 }77 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>78 where79 E: serde::de::Error,80 {81 Ok(Val::Num(v as f64))82 }8384 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>85 where86 E: serde::de::Error,87 {88 Ok(Val::Arr(ArrValue::bytes(v.into())))89 }9091 fn visit_none<E>(self) -> Result<Self::Value, E>92 where93 E: serde::de::Error,94 {95 Ok(Val::Null)96 }97 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>98 where99 D: serde::Deserializer<'de>,100 {101 deserializer.deserialize_any(self)102 }103104 fn visit_unit<E>(self) -> Result<Self::Value, E>105 where106 E: serde::de::Error,107 {108 Ok(Val::Null)109 }110111 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>112 where113 D: serde::Deserializer<'de>,114 {115 deserializer.deserialize_any(self)116 }117118 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>119 where120 A: serde::de::SeqAccess<'de>,121 {122 let mut out = seq.size_hint().map_or_else(Vec::new, Vec::with_capacity);123124 while let Some(val) = seq.next_element::<Val>()? {125 out.push(val);126 }127128 Ok(Val::Arr(ArrValue::eager(out)))129 }130131 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>132 where133 A: serde::de::MapAccess<'de>,134 {135 let mut out = map136 .size_hint()137 .map_or_else(ObjValueBuilder::new, ObjValueBuilder::with_capacity);138139 while let Some((k, v)) = map.next_entry::<Cow<'de, str>, Val>()? {140 // Jsonnet ignores duplicate keys141 out.member(k.into()).value_unchecked(v);142 }143144 Ok(Val::Obj(out.build()))145 }146147 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {148 write!(formatter, "any valid jsonnet value")149 }150 }151 deserializer.deserialize_any(ValVisitor)152 }153}154155impl Serialize for Val {156 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>157 where158 S: serde::Serializer,159 {160 match self {161 Val::Bool(v) => serializer.serialize_bool(*v),162 Val::Null => serializer.serialize_none(),163 Val::Str(s) => serializer.serialize_str(&s.clone().into_flat()),164 Val::Num(n) => serializer.serialize_f64(*n),165 Val::Arr(arr) => {166 let mut seq = serializer.serialize_seq(Some(arr.len()))?;167 for (i, element) in arr.iter().enumerate() {168 let mut serde_error = None;169 // TODO: rewrite using try{} after stabilization170 State::push_description(171 || format!("array index [{i}]"),172 || {173 let e = element?;174 if let Err(e) = seq.serialize_element(&e) {175 serde_error = Some(e);176 }177 Ok(())178 },179 )180 .map_err(|e| S::Error::custom(e.to_string()))?;181 if let Some(e) = serde_error {182 return Err(e);183 }184 }185 seq.end()186 }187 Val::Obj(obj) => {188 let mut map = serializer.serialize_map(Some(obj.len()))?;189 for (field, value) in obj.iter(190 #[cfg(feature = "exp-preserve-order")]191 true,192 ) {193 let mut serde_error = None;194 // TODO: rewrite using try{} after stabilization195 State::push_description(196 || format!("object field {field:?}"),197 || {198 let v = value?;199 if let Err(e) = map.serialize_entry(field.as_str(), &v) {200 serde_error = Some(e);201 }202 Ok(())203 },204 )205 .map_err(|e| S::Error::custom(e.to_string()))?;206 if let Some(e) = serde_error {207 return Err(e);208 }209 }210 map.end()211 }212 Val::Func(_) => Err(S::Error::custom("tried to manifest function")),213 }214 }215}216217struct IntoVecValSerializer {218 variant: Option<IStr>,219 data: Vec<Val>,220}221impl IntoVecValSerializer {222 fn new() -> Self {223 Self {224 variant: None,225 data: Vec::new(),226 }227 }228 fn with_capacity(capacity: usize) -> Self {229 Self {230 variant: None,231 data: Vec::with_capacity(capacity),232 }233 }234 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {235 Self {236 variant: Some(variant.into()),237 data: Vec::with_capacity(capacity),238 }239 }240}241impl SerializeSeq for IntoVecValSerializer {242 type Ok = Val;243 type Error = JrError;244245 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>246 where247 T: Serialize,248 {249 let value = value.serialize(IntoValSerializer)?;250 self.data.push(value);251 Ok(())252 }253254 fn end(self) -> Result<Val> {255 let inner = Val::Arr(ArrValue::eager(self.data));256 if let Some(variant) = self.variant {257 let mut out = ObjValue::builder_with_capacity(1);258 out.member(variant).value_unchecked(inner);259 Ok(Val::Obj(out.build()))260 } else {261 Ok(inner)262 }263 }264}265impl SerializeTuple for IntoVecValSerializer {266 type Ok = Val;267 type Error = JrError;268269 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>270 where271 T: Serialize,272 {273 SerializeSeq::serialize_element(self, value)274 }275276 fn end(self) -> Result<Val> {277 SerializeSeq::end(self)278 }279}280impl SerializeTupleVariant for IntoVecValSerializer {281 type Ok = Val;282 type Error = JrError;283284 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>285 where286 T: Serialize,287 {288 SerializeSeq::serialize_element(self, value)289 }290291 fn end(self) -> Result<Val> {292 SerializeSeq::end(self)293 }294}295impl SerializeTupleStruct for IntoVecValSerializer {296 type Ok = Val;297 type Error = JrError;298299 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>300 where301 T: Serialize,302 {303 SerializeSeq::serialize_element(self, value)304 }305306 fn end(self) -> Result<Val> {307 SerializeSeq::end(self)308 }309}310311struct IntoObjValueSerializer {312 variant: Option<IStr>,313 data: ObjValueBuilder,314 key: Option<IStr>,315}316impl IntoObjValueSerializer {317 fn new() -> Self {318 Self {319 variant: None,320 data: ObjValue::builder(),321 key: None,322 }323 }324 fn with_capacity(capacity: usize) -> Self {325 Self {326 variant: None,327 data: ObjValue::builder_with_capacity(capacity),328 key: None,329 }330 }331 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {332 Self {333 variant: Some(variant.into()),334 data: ObjValue::builder_with_capacity(capacity),335 key: None,336 }337 }338}339impl SerializeMap for IntoObjValueSerializer {340 type Ok = Val;341 type Error = JrError;342343 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>344 where345 T: Serialize,346 {347 let key = key.serialize(IntoValSerializer)?;348 let key = key.to_string()?;349 self.key = Some(key);350 Ok(())351 }352353 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>354 where355 T: Serialize,356 {357 let key = self.key.take().expect("no serialize_key called");358 let value = value.serialize(IntoValSerializer)?;359 self.data.member(key).value(value)?;360 Ok(())361 }362363 // TODO: serialize_key/serialize_value364 fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>365 where366 K: Serialize,367 V: Serialize,368 {369 let key = key.serialize(IntoValSerializer)?;370 let key = key.to_string()?;371 let value = value.serialize(IntoValSerializer)?;372 self.data.member(key).value(value)?;373 Ok(())374 }375376 fn end(self) -> Result<Val> {377 let inner = Val::Obj(self.data.build());378 if let Some(variant) = self.variant {379 let mut out = ObjValue::builder_with_capacity(1);380 out.member(variant).value_unchecked(inner);381 Ok(Val::Obj(out.build()))382 } else {383 Ok(inner)384 }385 }386}387impl SerializeStruct for IntoObjValueSerializer {388 type Ok = Val;389 type Error = JrError;390391 fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>392 where393 T: Serialize,394 {395 SerializeMap::serialize_entry(self, key, value)?;396 Ok(())397 }398399 fn end(self) -> Result<Val> {400 SerializeMap::end(self)401 }402}403impl SerializeStructVariant for IntoObjValueSerializer {404 type Ok = Val;405406 type Error = JrError;407408 fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>409 where410 T: Serialize,411 {412 SerializeMap::serialize_entry(self, key, value)?;413 Ok(())414 }415416 fn end(self) -> Result<Val> {417 SerializeMap::end(self)418 }419}420421struct IntoValSerializer;422impl Serializer for IntoValSerializer {423 type Ok = Val;424425 type Error = JrError;426427 type SerializeSeq = IntoVecValSerializer;428429 type SerializeTuple = IntoVecValSerializer;430431 type SerializeTupleStruct = IntoVecValSerializer;432433 type SerializeTupleVariant = IntoVecValSerializer;434435 type SerializeMap = IntoObjValueSerializer;436437 type SerializeStruct = IntoObjValueSerializer;438439 type SerializeStructVariant = IntoObjValueSerializer;440441 fn serialize_bool(self, v: bool) -> Result<Val> {442 Ok(Val::Bool(v))443 }444445 fn serialize_i8(self, v: i8) -> Result<Val> {446 Ok(Val::Num(f64::from(v)))447 }448449 fn serialize_i16(self, v: i16) -> Result<Val> {450 Ok(Val::Num(f64::from(v)))451 }452453 fn serialize_i32(self, v: i32) -> Result<Val> {454 Ok(Val::Num(f64::from(v)))455 }456457 fn serialize_i64(self, v: i64) -> Result<Val> {458 Ok(Val::Str(v.to_string().into()))459 }460461 fn serialize_u8(self, v: u8) -> Result<Val> {462 Ok(Val::Num(f64::from(v)))463 }464465 fn serialize_u16(self, v: u16) -> Result<Val> {466 Ok(Val::Num(f64::from(v)))467 }468469 fn serialize_u32(self, v: u32) -> Result<Val> {470 Ok(Val::Num(f64::from(v)))471 }472473 fn serialize_u64(self, v: u64) -> Result<Val> {474 Ok(Val::Str(v.to_string().into()))475 }476477 fn serialize_f32(self, v: f32) -> Result<Val> {478 Ok(Val::Num(f64::from(v)))479 }480481 fn serialize_f64(self, v: f64) -> Result<Val> {482 Ok(Val::Num(v))483 }484485 fn serialize_char(self, v: char) -> Result<Val> {486 Ok(Val::Str(v.to_string().into()))487 }488489 fn serialize_str(self, v: &str) -> Result<Val> {490 Ok(Val::Str(v.into()))491 }492493 fn serialize_bytes(self, v: &[u8]) -> Result<Val> {494 Ok(Val::Arr(ArrValue::bytes(v.into())))495 }496497 fn serialize_none(self) -> Result<Val> {498 Ok(Val::Null)499 }500501 fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Val>502 where503 T: Serialize,504 {505 value.serialize(self)506 }507508 fn serialize_unit(self) -> Result<Val> {509 Ok(Val::Null)510 }511512 fn serialize_unit_struct(self, _name: &'static str) -> Result<Val> {513 Ok(Val::Null)514 }515516 fn serialize_unit_variant(517 self,518 _name: &'static str,519 _variant_index: u32,520 variant: &'static str,521 ) -> Result<Val> {522 Ok(Val::Str(variant.into()))523 }524525 fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Val>526 where527 T: Serialize,528 {529 value.serialize(self)530 }531532 fn serialize_newtype_variant<T: ?Sized>(533 self,534 _name: &'static str,535 _variant_index: u32,536 variant: &'static str,537 value: &T,538 ) -> Result<Val>539 where540 T: Serialize,541 {542 let mut out = ObjValue::builder_with_capacity(1);543 let value = value.serialize(self)?;544 out.member(variant.into()).value_unchecked(value);545 Ok(Val::Obj(out.build()))546 }547548 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {549 Ok(len.map_or_else(550 IntoVecValSerializer::new,551 IntoVecValSerializer::with_capacity,552 ))553 }554555 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {556 Ok(IntoVecValSerializer::with_capacity(len))557 }558559 fn serialize_tuple_struct(560 self,561 _name: &'static str,562 len: usize,563 ) -> Result<Self::SerializeTupleStruct, Self::Error> {564 Ok(IntoVecValSerializer::with_capacity(len))565 }566567 fn serialize_tuple_variant(568 self,569 _name: &'static str,570 _variant_index: u32,571 variant: &'static str,572 len: usize,573 ) -> Result<Self::SerializeTupleVariant, Self::Error> {574 Ok(IntoVecValSerializer::variant_with_capacity(variant, len))575 }576577 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {578 Ok(len.map_or_else(579 IntoObjValueSerializer::new,580 IntoObjValueSerializer::with_capacity,581 ))582 }583584 fn serialize_struct(585 self,586 _name: &'static str,587 len: usize,588 ) -> Result<Self::SerializeStruct, Self::Error> {589 Ok(IntoObjValueSerializer::with_capacity(len))590 }591592 fn serialize_struct_variant(593 self,594 _name: &'static str,595 _variant_index: u32,596 variant: &'static str,597 len: usize,598 ) -> Result<Self::SerializeStructVariant, Self::Error> {599 Ok(IntoObjValueSerializer::variant_with_capacity(variant, len))600 }601}602603impl Val {604 pub fn from_serde(v: impl Serialize) -> Result<Val, JrError> {605 v.serialize(IntoValSerializer)606 }607}608609impl serde::ser::Error for JrError {610 fn custom<T>(msg: T) -> Self611 where612 T: std::fmt::Display,613 {614 JrError::new(ErrorKind::RuntimeError(format!("serde: {msg}").into()))615 }616}1use std::borrow::Cow;23use jrsonnet_interner::IStr;4use serde::{5 de::Visitor,6 ser::{7 Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,8 SerializeTupleStruct, SerializeTupleVariant,9 },10 Deserialize, Serialize, Serializer,11};1213use crate::{14 arr::ArrValue,15 error::{Error as JrError, ErrorKind, Result},16 val::StrValue,17 ObjValue, ObjValueBuilder, State, Val,18};1920impl<'de> Deserialize<'de> for Val {21 fn deserialize<D>(deserializer: D) -> Result<Val, D::Error>22 where23 D: serde::Deserializer<'de>,24 {25 struct ValVisitor;2627 // macro_rules! visit_num {28 // ($($method:ident => $ty:ty),* $(,)?) => {$(29 // fn $method<E>(self, v: $ty) -> Result<Self::Value, E>30 // where31 // E: serde::de::Error,32 // {33 // Ok(Val::Num(f64::from(v)))34 // }35 // )*};36 // }3738 impl<'de> Visitor<'de> for ValVisitor {39 type Value = Val;4041 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>42 where43 E: serde::de::Error,44 {45 Ok(Val::Bool(v))46 }47 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>48 where49 E: serde::de::Error,50 {51 if !v.is_finite() {52 return Err(E::custom("only finite numbers are supported"));53 }54 Ok(Val::Num(v))55 }56 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>57 where58 E: serde::de::Error,59 {60 Ok(Val::Str(StrValue::Flat(v.into())))61 }6263 // visit_num! {64 // visit_i8 => i8,65 // visit_i16 => i16,66 // visit_i32 => i32,67 // visit_u8 => u8,68 // visit_u16 => u16,69 // visit_u32 => u32,70 // }71 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>72 where73 E: serde::de::Error,74 {75 Ok(Val::Num(v as f64))76 }77 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>78 where79 E: serde::de::Error,80 {81 Ok(Val::Num(v as f64))82 }8384 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>85 where86 E: serde::de::Error,87 {88 Ok(Val::Arr(ArrValue::bytes(v.into())))89 }9091 fn visit_none<E>(self) -> Result<Self::Value, E>92 where93 E: serde::de::Error,94 {95 Ok(Val::Null)96 }97 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>98 where99 D: serde::Deserializer<'de>,100 {101 deserializer.deserialize_any(self)102 }103104 fn visit_unit<E>(self) -> Result<Self::Value, E>105 where106 E: serde::de::Error,107 {108 Ok(Val::Null)109 }110111 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>112 where113 D: serde::Deserializer<'de>,114 {115 deserializer.deserialize_any(self)116 }117118 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>119 where120 A: serde::de::SeqAccess<'de>,121 {122 let mut out = seq.size_hint().map_or_else(Vec::new, Vec::with_capacity);123124 while let Some(val) = seq.next_element::<Val>()? {125 out.push(val);126 }127128 Ok(Val::Arr(ArrValue::eager(out)))129 }130131 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>132 where133 A: serde::de::MapAccess<'de>,134 {135 let mut out = map136 .size_hint()137 .map_or_else(ObjValueBuilder::new, ObjValueBuilder::with_capacity);138139 while let Some((k, v)) = map.next_entry::<Cow<'de, str>, Val>()? {140 // Jsonnet ignores duplicate keys141 out.member(k.into()).value_unchecked(v);142 }143144 Ok(Val::Obj(out.build()))145 }146147 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {148 write!(formatter, "any valid jsonnet value")149 }150 }151 deserializer.deserialize_any(ValVisitor)152 }153}154155impl Serialize for Val {156 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>157 where158 S: serde::Serializer,159 {160 match self {161 Val::Bool(v) => serializer.serialize_bool(*v),162 Val::Null => serializer.serialize_none(),163 Val::Str(s) => serializer.serialize_str(&s.clone().into_flat()),164 Val::Num(n) => serializer.serialize_f64(*n),165 #[cfg(feature = "exp-bigint")]166 Val::BigInt(b) => b.serialize(serializer),167 Val::Arr(arr) => {168 let mut seq = serializer.serialize_seq(Some(arr.len()))?;169 for (i, element) in arr.iter().enumerate() {170 let mut serde_error = None;171 // TODO: rewrite using try{} after stabilization172 State::push_description(173 || format!("array index [{i}]"),174 || {175 let e = element?;176 if let Err(e) = seq.serialize_element(&e) {177 serde_error = Some(e);178 }179 Ok(())180 },181 )182 .map_err(|e| S::Error::custom(e.to_string()))?;183 if let Some(e) = serde_error {184 return Err(e);185 }186 }187 seq.end()188 }189 Val::Obj(obj) => {190 let mut map = serializer.serialize_map(Some(obj.len()))?;191 for (field, value) in obj.iter(192 #[cfg(feature = "exp-preserve-order")]193 true,194 ) {195 let mut serde_error = None;196 // TODO: rewrite using try{} after stabilization197 State::push_description(198 || format!("object field {field:?}"),199 || {200 let v = value?;201 if let Err(e) = map.serialize_entry(field.as_str(), &v) {202 serde_error = Some(e);203 }204 Ok(())205 },206 )207 .map_err(|e| S::Error::custom(e.to_string()))?;208 if let Some(e) = serde_error {209 return Err(e);210 }211 }212 map.end()213 }214 Val::Func(_) => Err(S::Error::custom("tried to manifest function")),215 }216 }217}218219struct IntoVecValSerializer {220 variant: Option<IStr>,221 data: Vec<Val>,222}223impl IntoVecValSerializer {224 fn new() -> Self {225 Self {226 variant: None,227 data: Vec::new(),228 }229 }230 fn with_capacity(capacity: usize) -> Self {231 Self {232 variant: None,233 data: Vec::with_capacity(capacity),234 }235 }236 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {237 Self {238 variant: Some(variant.into()),239 data: Vec::with_capacity(capacity),240 }241 }242}243impl SerializeSeq for IntoVecValSerializer {244 type Ok = Val;245 type Error = JrError;246247 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>248 where249 T: Serialize,250 {251 let value = value.serialize(IntoValSerializer)?;252 self.data.push(value);253 Ok(())254 }255256 fn end(self) -> Result<Val> {257 let inner = Val::Arr(ArrValue::eager(self.data));258 if let Some(variant) = self.variant {259 let mut out = ObjValue::builder_with_capacity(1);260 out.member(variant).value_unchecked(inner);261 Ok(Val::Obj(out.build()))262 } else {263 Ok(inner)264 }265 }266}267impl SerializeTuple for IntoVecValSerializer {268 type Ok = Val;269 type Error = JrError;270271 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>272 where273 T: Serialize,274 {275 SerializeSeq::serialize_element(self, value)276 }277278 fn end(self) -> Result<Val> {279 SerializeSeq::end(self)280 }281}282impl SerializeTupleVariant for IntoVecValSerializer {283 type Ok = Val;284 type Error = JrError;285286 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>287 where288 T: Serialize,289 {290 SerializeSeq::serialize_element(self, value)291 }292293 fn end(self) -> Result<Val> {294 SerializeSeq::end(self)295 }296}297impl SerializeTupleStruct for IntoVecValSerializer {298 type Ok = Val;299 type Error = JrError;300301 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>302 where303 T: Serialize,304 {305 SerializeSeq::serialize_element(self, value)306 }307308 fn end(self) -> Result<Val> {309 SerializeSeq::end(self)310 }311}312313struct IntoObjValueSerializer {314 variant: Option<IStr>,315 data: ObjValueBuilder,316 key: Option<IStr>,317}318impl IntoObjValueSerializer {319 fn new() -> Self {320 Self {321 variant: None,322 data: ObjValue::builder(),323 key: None,324 }325 }326 fn with_capacity(capacity: usize) -> Self {327 Self {328 variant: None,329 data: ObjValue::builder_with_capacity(capacity),330 key: None,331 }332 }333 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {334 Self {335 variant: Some(variant.into()),336 data: ObjValue::builder_with_capacity(capacity),337 key: None,338 }339 }340}341impl SerializeMap for IntoObjValueSerializer {342 type Ok = Val;343 type Error = JrError;344345 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>346 where347 T: Serialize,348 {349 let key = key.serialize(IntoValSerializer)?;350 let key = key.to_string()?;351 self.key = Some(key);352 Ok(())353 }354355 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>356 where357 T: Serialize,358 {359 let key = self.key.take().expect("no serialize_key called");360 let value = value.serialize(IntoValSerializer)?;361 self.data.member(key).value(value)?;362 Ok(())363 }364365 // TODO: serialize_key/serialize_value366 fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>367 where368 K: Serialize,369 V: Serialize,370 {371 let key = key.serialize(IntoValSerializer)?;372 let key = key.to_string()?;373 let value = value.serialize(IntoValSerializer)?;374 self.data.member(key).value(value)?;375 Ok(())376 }377378 fn end(self) -> Result<Val> {379 let inner = Val::Obj(self.data.build());380 if let Some(variant) = self.variant {381 let mut out = ObjValue::builder_with_capacity(1);382 out.member(variant).value_unchecked(inner);383 Ok(Val::Obj(out.build()))384 } else {385 Ok(inner)386 }387 }388}389impl SerializeStruct for IntoObjValueSerializer {390 type Ok = Val;391 type Error = JrError;392393 fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>394 where395 T: Serialize,396 {397 SerializeMap::serialize_entry(self, key, value)?;398 Ok(())399 }400401 fn end(self) -> Result<Val> {402 SerializeMap::end(self)403 }404}405impl SerializeStructVariant for IntoObjValueSerializer {406 type Ok = Val;407408 type Error = JrError;409410 fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>411 where412 T: Serialize,413 {414 SerializeMap::serialize_entry(self, key, value)?;415 Ok(())416 }417418 fn end(self) -> Result<Val> {419 SerializeMap::end(self)420 }421}422423struct IntoValSerializer;424impl Serializer for IntoValSerializer {425 type Ok = Val;426427 type Error = JrError;428429 type SerializeSeq = IntoVecValSerializer;430431 type SerializeTuple = IntoVecValSerializer;432433 type SerializeTupleStruct = IntoVecValSerializer;434435 type SerializeTupleVariant = IntoVecValSerializer;436437 type SerializeMap = IntoObjValueSerializer;438439 type SerializeStruct = IntoObjValueSerializer;440441 type SerializeStructVariant = IntoObjValueSerializer;442443 fn serialize_bool(self, v: bool) -> Result<Val> {444 Ok(Val::Bool(v))445 }446447 fn serialize_i8(self, v: i8) -> Result<Val> {448 Ok(Val::Num(f64::from(v)))449 }450451 fn serialize_i16(self, v: i16) -> Result<Val> {452 Ok(Val::Num(f64::from(v)))453 }454455 fn serialize_i32(self, v: i32) -> Result<Val> {456 Ok(Val::Num(f64::from(v)))457 }458459 fn serialize_i64(self, v: i64) -> Result<Val> {460 Ok(Val::Str(v.to_string().into()))461 }462463 fn serialize_u8(self, v: u8) -> Result<Val> {464 Ok(Val::Num(f64::from(v)))465 }466467 fn serialize_u16(self, v: u16) -> Result<Val> {468 Ok(Val::Num(f64::from(v)))469 }470471 fn serialize_u32(self, v: u32) -> Result<Val> {472 Ok(Val::Num(f64::from(v)))473 }474475 fn serialize_u64(self, v: u64) -> Result<Val> {476 Ok(Val::Str(v.to_string().into()))477 }478479 fn serialize_f32(self, v: f32) -> Result<Val> {480 Ok(Val::Num(f64::from(v)))481 }482483 fn serialize_f64(self, v: f64) -> Result<Val> {484 Ok(Val::Num(v))485 }486487 fn serialize_char(self, v: char) -> Result<Val> {488 Ok(Val::Str(v.to_string().into()))489 }490491 fn serialize_str(self, v: &str) -> Result<Val> {492 Ok(Val::Str(v.into()))493 }494495 fn serialize_bytes(self, v: &[u8]) -> Result<Val> {496 Ok(Val::Arr(ArrValue::bytes(v.into())))497 }498499 fn serialize_none(self) -> Result<Val> {500 Ok(Val::Null)501 }502503 fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Val>504 where505 T: Serialize,506 {507 value.serialize(self)508 }509510 fn serialize_unit(self) -> Result<Val> {511 Ok(Val::Null)512 }513514 fn serialize_unit_struct(self, _name: &'static str) -> Result<Val> {515 Ok(Val::Null)516 }517518 fn serialize_unit_variant(519 self,520 _name: &'static str,521 _variant_index: u32,522 variant: &'static str,523 ) -> Result<Val> {524 Ok(Val::Str(variant.into()))525 }526527 fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Val>528 where529 T: Serialize,530 {531 value.serialize(self)532 }533534 fn serialize_newtype_variant<T: ?Sized>(535 self,536 _name: &'static str,537 _variant_index: u32,538 variant: &'static str,539 value: &T,540 ) -> Result<Val>541 where542 T: Serialize,543 {544 let mut out = ObjValue::builder_with_capacity(1);545 let value = value.serialize(self)?;546 out.member(variant.into()).value_unchecked(value);547 Ok(Val::Obj(out.build()))548 }549550 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {551 Ok(len.map_or_else(552 IntoVecValSerializer::new,553 IntoVecValSerializer::with_capacity,554 ))555 }556557 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {558 Ok(IntoVecValSerializer::with_capacity(len))559 }560561 fn serialize_tuple_struct(562 self,563 _name: &'static str,564 len: usize,565 ) -> Result<Self::SerializeTupleStruct, Self::Error> {566 Ok(IntoVecValSerializer::with_capacity(len))567 }568569 fn serialize_tuple_variant(570 self,571 _name: &'static str,572 _variant_index: u32,573 variant: &'static str,574 len: usize,575 ) -> Result<Self::SerializeTupleVariant, Self::Error> {576 Ok(IntoVecValSerializer::variant_with_capacity(variant, len))577 }578579 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {580 Ok(len.map_or_else(581 IntoObjValueSerializer::new,582 IntoObjValueSerializer::with_capacity,583 ))584 }585586 fn serialize_struct(587 self,588 _name: &'static str,589 len: usize,590 ) -> Result<Self::SerializeStruct, Self::Error> {591 Ok(IntoObjValueSerializer::with_capacity(len))592 }593594 fn serialize_struct_variant(595 self,596 _name: &'static str,597 _variant_index: u32,598 variant: &'static str,599 len: usize,600 ) -> Result<Self::SerializeStructVariant, Self::Error> {601 Ok(IntoObjValueSerializer::variant_with_capacity(variant, len))602 }603}604605impl Val {606 pub fn from_serde(v: impl Serialize) -> Result<Val, JrError> {607 v.serialize(IntoValSerializer)608 }609}610611impl serde::ser::Error for JrError {612 fn custom<T>(msg: T) -> Self613 where614 T: std::fmt::Display,615 {616 JrError::new(ErrorKind::RuntimeError(format!("serde: {msg}").into()))617 }618}crates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/manifest.rs
@@ -149,6 +149,8 @@
Val::Null => buf.push_str("null"),
Val::Str(s) => escape_string_json_buf(&s.clone().into_flat(), buf),
Val::Num(n) => write!(buf, "{n}").unwrap(),
+ #[cfg(feature = "exp-bigint")]
+ Val::BigInt(n) => write!(buf, "{n}").unwrap(),
Val::Arr(items) => {
buf.push('[');
if !items.is_empty() {
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -311,6 +311,9 @@
/// Should be finite, and not NaN
/// This restriction isn't enforced by enum, as enum field can't be marked as private
Num(f64),
+ /// Experimental bigint
+ #[cfg(feature = "exp-bigint")]
+ BigInt(#[trace(skip)] Box<num_bigint::BigInt>),
/// Represents a Jsonnet array.
Arr(ArrValue),
/// Represents a Jsonnet object.
@@ -389,6 +392,8 @@
match self {
Self::Str(..) => ValType::Str,
Self::Num(..) => ValType::Num,
+ #[cfg(feature = "exp-bigint")]
+ Self::BigInt(..) => ValType::BigInt,
Self::Arr(..) => ValType::Arr,
Self::Obj(..) => ValType::Obj,
Self::Bool(_) => ValType::Bool,
crates/jrsonnet-stdlib/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-stdlib/Cargo.toml
+++ b/crates/jrsonnet-stdlib/Cargo.toml
@@ -17,6 +17,8 @@
exp-preserve-order = ["jrsonnet-evaluator/exp-preserve-order"]
# Add nonstandard `std.sha256` function
exp-more-hashes = ["dep:sha2"]
+# Bigint type
+exp-bigint = ["num-bigint", "jrsonnet-evaluator/exp-bigint"]
[dependencies]
jrsonnet-evaluator.workspace = true
@@ -39,6 +41,7 @@
serde_yaml_with_quirks = "0.8.24"
sha2 = { version = "0.10.6", optional = true }
+num-bigint = { version = "0.4.3", optional = true }
[build-dependencies]
jrsonnet-parser.workspace = true
crates/jrsonnet-stdlib/src/expr.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/expr.rs
+++ b/crates/jrsonnet-stdlib/src/expr.rs
@@ -83,7 +83,7 @@
pub(super) use std::{option::Option, rc::Rc, vec};
pub(super) use jrsonnet_parser::*;
- };
+ }
include!(concat!(env!("OUT_DIR"), "/stdlib.rs"))
}
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -143,6 +143,8 @@
("asciiLower", builtin_ascii_lower::INST),
("findSubstr", builtin_find_substr::INST),
("parseInt", builtin_parse_int::INST),
+ #[cfg(feature = "exp-bigint")]
+ ("bigint", builtin_bigint::INST),
("parseOctal", builtin_parse_octal::INST),
("parseHex", builtin_parse_hex::INST),
// Misc
crates/jrsonnet-stdlib/src/manifest/toml.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/toml.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/toml.rs
@@ -103,6 +103,8 @@
escape_string_json_buf(&s.clone().into_flat(), buf);
}
Val::Num(n) => write!(buf, "{n}").unwrap(),
+ #[cfg(feature = "exp-bigint")]
+ Val::BigInt(n) => write!(buf, "{n}").unwrap(),
Val::Arr(a) => {
if a.is_empty() {
buf.push_str("[]");
crates/jrsonnet-stdlib/src/manifest/yaml.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/yaml.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/yaml.rs
@@ -140,6 +140,8 @@
}
}
Val::Num(n) => write!(buf, "{}", *n).unwrap(),
+ #[cfg(feature = "exp-bigint")]
+ Val::BigInt(n) => write!(buf, "{}", *n).unwrap(),
Val::Arr(a) => {
if a.is_empty() {
buf.push_str("[]");
crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/strings.rs
+++ b/crates/jrsonnet-stdlib/src/strings.rs
@@ -151,6 +151,20 @@
})
}
+#[cfg(feature = "exp-bigint")]
+#[builtin]
+pub fn builtin_bigint(v: Either![f64, IStr]) -> Result<Val> {
+ use Either2::*;
+ Ok(match v {
+ A(a) => Val::BigInt(Box::new((a as i64).into())),
+ B(b) => Val::BigInt(Box::new(
+ b.as_str()
+ .parse()
+ .map_err(|e| RuntimeError(format!("bad bigint: {e}").into()))?,
+ )),
+ })
+}
+
#[cfg(test)]
mod tests {
use super::*;
crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -88,6 +88,8 @@
Null,
Str,
Num,
+ #[cfg(feature = "exp-bigint")]
+ BigInt,
Arr,
Obj,
Func,
@@ -101,6 +103,8 @@
Null => "null",
Str => "string",
Num => "number",
+ #[cfg(feature = "exp-bigint")]
+ BigInt => "bigint",
Arr => "array",
Obj => "object",
Func => "function",