difftreelog
refactor fix clippy warnings
in: master
27 files changed
Cargo.tomldiffbeforeafterboth150redundant_pub_crate = "allow"150redundant_pub_crate = "allow"151# Sometimes code is fancier without that151# Sometimes code is fancier without that152manual_let_else = "allow"152manual_let_else = "allow"153# Something is broken about that lint, can't be allowed for154# codegenerated-stdlib block155similar_names = "allow"153156154#[profile.test]157#[profile.test]155#opt-level = 1158#opt-level = 1cmds/jrsonnet-fmt/src/tests.rsdiffbeforeafterboth1use dprint_core::formatting::{PrintOptions, PrintItems};1use dprint_core::formatting::{PrintItems, PrintOptions};2use indoc::indoc;2use indoc::indoc;334use crate::Printable;4use crate::Printable;cmds/jrsonnet/src/main.rsdiffbeforeafterboth153 if let Error::Evaluation(e) = e {153 if let Error::Evaluation(e) = e {154 let mut out = String::new();154 let mut out = String::new();155 trace.write_trace(&mut out, &e).expect("format error");155 trace.write_trace(&mut out, &e).expect("format error");156 eprintln!("{out}")156 eprintln!("{out}");157 } else {157 } else {158 eprintln!("{e}");158 eprintln!("{e}");159 }159 }crates/jrsonnet-cli/src/lib.rsdiffbeforeafterboth10 stack::{limit_stack_depth, StackDepthLimitOverrideGuard},10 stack::{limit_stack_depth, StackDepthLimitOverrideGuard},11 FileImportResolver,11 FileImportResolver,12};12};13use jrsonnet_gcmodule::with_thread_object_space;13use jrsonnet_gcmodule::{with_thread_object_space, ObjectSpace};14pub use manifest::*;14pub use manifest::*;15pub use stdlib::*;15pub use stdlib::*;16pub use tla::*;16pub use tla::*;888889impl Drop for LeakSpace {89impl Drop for LeakSpace {90 fn drop(&mut self) {90 fn drop(&mut self) {91 with_thread_object_space(|s| s.leak())91 with_thread_object_space(ObjectSpace::leak);92 }92 }93}93}9494102 let collected = jrsonnet_gcmodule::collect_thread_cycles();102 let collected = jrsonnet_gcmodule::collect_thread_cycles();103 eprintln!("Collected: {collected}");103 eprintln!("Collected: {collected}");104 }104 }105 eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked())105 eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked());106 }106 }107}107}108108crates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth393940 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {40 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {41 match s.find('=') {41 match s.find('=') {42 Some(idx) => Ok(ExtStr {42 Some(idx) => Ok(Self {43 name: s[..idx].to_owned(),43 name: s[..idx].to_owned(),44 value: s[idx + 1..].to_owned(),44 value: s[idx + 1..].to_owned(),45 }),45 }),46 None => Ok(ExtStr {46 None => Ok(Self {47 name: s.to_owned(),47 name: s.to_owned(),48 value: std::env::var(s).or(Err("missing env var"))?,48 value: std::env::var(s).or(Err("missing env var"))?,49 }),49 }),109 return Ok(None);109 return Ok(None);110 }110 }111 let ctx = ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());111 let ctx = ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());112 for ext in self.ext_str.iter() {112 for ext in &self.ext_str {113 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());113 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());114 }114 }115 for ext in self.ext_str_file.iter() {115 for ext in &self.ext_str_file {116 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());116 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());117 }117 }118 for ext in self.ext_code.iter() {118 for ext in &self.ext_code {119 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;119 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;120 }120 }121 for ext in self.ext_code_file.iter() {121 for ext in &self.ext_code_file {122 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;122 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;123 }123 }124 Ok(Some(ctx))124 Ok(Some(ctx))crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth42 Self::new(EagerArray(values))42 Self::new(EagerArray(values))43 }43 }444445 pub fn repeated(data: ArrValue, repeats: usize) -> Option<Self> {45 pub fn repeated(data: Self, repeats: usize) -> Option<Self> {46 Some(Self::new(RepeatedArray::new(data, repeats)?))46 Some(Self::new(RepeatedArray::new(data, repeats)?))47 }47 }484870 Ok(Self::eager(out))70 Ok(Self::eager(out))71 }71 }727273 pub fn extended(a: ArrValue, b: ArrValue) -> Self {73 pub fn extended(a: Self, b: Self) -> Self {74 // TODO: benchmark for an optimal value, currently just a arbitrary choice74 // TODO: benchmark for an optimal value, currently just a arbitrary choice75 const ARR_EXTEND_THRESHOLD: usize = 100;75 const ARR_EXTEND_THRESHOLD: usize = 100;7676crates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth61impl ArgLike for TlaArg {61impl ArgLike for TlaArg {62 fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {62 fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {63 match self {63 match self {64 TlaArg::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),64 Self::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),65 TlaArg::Code(code) => Ok(if tailstrict {65 Self::Code(code) => Ok(if tailstrict {66 Thunk::evaluated(evaluate(ctx, code)?)66 Thunk::evaluated(evaluate(ctx, code)?)67 } else {67 } else {68 Thunk::new(EvaluateThunk {68 Thunk::new(EvaluateThunk {69 ctx,69 ctx,70 expr: code.clone(),70 expr: code.clone(),71 })71 })72 }),72 }),73 TlaArg::Val(val) => Ok(Thunk::evaluated(val.clone())),73 Self::Val(val) => Ok(Thunk::evaluated(val.clone())),74 TlaArg::Lazy(lazy) => Ok(lazy.clone()),74 Self::Lazy(lazy) => Ok(lazy.clone()),75 }75 }76 }76 }77}77}crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth237237238 pub fn evaluate_trivial(&self) -> Option<Val> {238 pub fn evaluate_trivial(&self) -> Option<Val> {239 match self {239 match self {240 FuncVal::Normal(n) => n.evaluate_trivial(),240 Self::Normal(n) => n.evaluate_trivial(),241 _ => None,241 _ => None,242 }242 }243 }243 }crates/jrsonnet-evaluator/src/import.rsdiffbeforeafterboth10use fs::File;10use fs::File;11use jrsonnet_gcmodule::Trace;11use jrsonnet_gcmodule::Trace;12use jrsonnet_interner::IBytes;12use jrsonnet_interner::IBytes;13use jrsonnet_parser::{SourceDirectory, SourceFile, SourcePath, SourceFifo};13use jrsonnet_parser::{SourceDirectory, SourceFifo, SourceFile, SourcePath};141415use crate::{15use crate::{16 bail,16 bail,crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth15};15};161617impl<'de> Deserialize<'de> for Val {17impl<'de> Deserialize<'de> for Val {18 fn deserialize<D>(deserializer: D) -> Result<Val, D::Error>18 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>19 where19 where20 D: serde::Deserializer<'de>,20 D: serde::Deserializer<'de>,21 {21 {155 S: serde::Serializer,155 S: serde::Serializer,156 {156 {157 match self {157 match self {158 Val::Bool(v) => serializer.serialize_bool(*v),158 Self::Bool(v) => serializer.serialize_bool(*v),159 Val::Null => serializer.serialize_none(),159 Self::Null => serializer.serialize_none(),160 Val::Str(s) => serializer.serialize_str(&s.clone().into_flat()),160 Self::Str(s) => serializer.serialize_str(&s.clone().into_flat()),161 Val::Num(n) => {161 Self::Num(n) => {162 if n.fract() == 0.0 {162 if n.fract() == 0.0 {163 let n = *n as i64;163 let n = *n as i64;164 serializer.serialize_i64(n)164 serializer.serialize_i64(n)167 }167 }168 }168 }169 #[cfg(feature = "exp-bigint")]169 #[cfg(feature = "exp-bigint")]170 Val::BigInt(b) => b.serialize(serializer),170 Self::BigInt(b) => b.serialize(serializer),171 Val::Arr(arr) => {171 Self::Arr(arr) => {172 let mut seq = serializer.serialize_seq(Some(arr.len()))?;172 let mut seq = serializer.serialize_seq(Some(arr.len()))?;173 for (i, element) in arr.iter().enumerate() {173 for (i, element) in arr.iter().enumerate() {174 let mut serde_error = None;174 let mut serde_error = None;190 }190 }191 seq.end()191 seq.end()192 }192 }193 Val::Obj(obj) => {193 Self::Obj(obj) => {194 let mut map = serializer.serialize_map(Some(obj.len()))?;194 let mut map = serializer.serialize_map(Some(obj.len()))?;195 for (field, value) in obj.iter(195 for (field, value) in obj.iter(196 #[cfg(feature = "exp-preserve-order")]196 #[cfg(feature = "exp-preserve-order")]215 }215 }216 map.end()216 map.end()217 }217 }218 Val::Func(_) => Err(S::Error::custom("tried to manifest function")),218 Self::Func(_) => Err(S::Error::custom("tried to manifest function")),219 }219 }220 }220 }221}221}248 type Ok = Val;248 type Ok = Val;249 type Error = JrError;249 type Error = JrError;250250251 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>251 fn serialize_element<T>(&mut self, value: &T) -> Result<()>252 where252 where253 T: Serialize,253 T: ?Sized + Serialize,254 {254 {255 let value = value.serialize(IntoValSerializer)?;255 let value = value.serialize(IntoValSerializer)?;256 self.data.push(value);256 self.data.push(value);272 type Ok = Val;272 type Ok = Val;273 type Error = JrError;273 type Error = JrError;274274275 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>275 fn serialize_element<T>(&mut self, value: &T) -> Result<()>276 where276 where277 T: Serialize,277 T: ?Sized + Serialize,278 {278 {279 SerializeSeq::serialize_element(self, value)279 SerializeSeq::serialize_element(self, value)280 }280 }287 type Ok = Val;287 type Ok = Val;288 type Error = JrError;288 type Error = JrError;289289290 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>290 fn serialize_field<T>(&mut self, value: &T) -> Result<()>291 where291 where292 T: Serialize,292 T: ?Sized + Serialize,293 {293 {294 SerializeSeq::serialize_element(self, value)294 SerializeSeq::serialize_element(self, value)295 }295 }302 type Ok = Val;302 type Ok = Val;303 type Error = JrError;303 type Error = JrError;304304305 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>305 fn serialize_field<T>(&mut self, value: &T) -> Result<()>306 where306 where307 T: Serialize,307 T: ?Sized + Serialize,308 {308 {309 SerializeSeq::serialize_element(self, value)309 SerializeSeq::serialize_element(self, value)310 }310 }607}607}608608609impl Val {609impl Val {610 pub fn from_serde(v: impl Serialize) -> Result<Val, JrError> {610 pub fn from_serde(v: impl Serialize) -> Result<Self, JrError> {611 v.serialize(IntoValSerializer)611 v.serialize(IntoValSerializer)612 }612 }613}613}crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth45#[doc(hidden)]45#[doc(hidden)]46pub use jrsonnet_macros;46pub use jrsonnet_macros;47pub use jrsonnet_parser as parser;47pub use jrsonnet_parser as parser;48use jrsonnet_parser::*;48use jrsonnet_parser::{ExprLocation, LocExpr, ParserSettings, Source, SourcePath};49pub use obj::*;49pub use obj::*;50use stack::check_depth;50use stack::check_depth;51pub use tla::apply_tla;51pub use tla::apply_tla;crates/jrsonnet-evaluator/src/stack.rsdiffbeforeafterboth24pub struct StackOverflowError;24pub struct StackOverflowError;25impl From<StackOverflowError> for ErrorKind {25impl From<StackOverflowError> for ErrorKind {26 fn from(_: StackOverflowError) -> Self {26 fn from(_: StackOverflowError) -> Self {27 ErrorKind::StackOverflow27 Self::StackOverflow28 }28 }29}29}30impl From<StackOverflowError> for Error {30impl From<StackOverflowError> for Error {crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth358 };358 };359 a.iter()359 a.iter()360 .map(|r| r.and_then(T::from_untyped))360 .map(|r| r.and_then(T::from_untyped))361 .collect::<Result<Vec<T>>>()361 .collect::<Result<Self>>()362 }362 }363}363}364364381 Self::TYPE.check(&value)?;381 Self::TYPE.check(&value)?;382 let obj = value.as_obj().expect("typecheck should fail");382 let obj = value.as_obj().expect("typecheck should fail");383383384 let mut out = BTreeMap::new();384 let mut out = Self::new();385 if V::wants_lazy() {385 if V::wants_lazy() {386 for key in obj.fields_ex(386 for key in obj.fields_ex(387 false,387 false,623623624 fn into_untyped(value: Self) -> Result<Val> {624 fn into_untyped(value: Self) -> Result<Val> {625 match value {625 match value {626 IndexableVal::Str(s) => Ok(Val::string(s)),626 Self::Str(s) => Ok(Val::string(s)),627 IndexableVal::Arr(a) => Ok(Val::Arr(a)),627 Self::Arr(a) => Ok(Val::Arr(a)),628 }628 }629 }629 }630630crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth147 T: ThunkValue<Output = V>,147 T: ThunkValue<Output = V>,148{148{149 fn from(value: T) -> Self {149 fn from(value: T) -> Self {150 Thunk::new(value)150 Self::new(value)151 }151 }152}152}153153221impl IndexableVal {221impl IndexableVal {222 pub fn to_array(self) -> ArrValue {222 pub fn to_array(self) -> ArrValue {223 match self {223 match self {224 IndexableVal::Str(s) => ArrValue::chars(s.chars()),224 Self::Str(s) => ArrValue::chars(s.chars()),225 IndexableVal::Arr(arr) => arr,225 Self::Arr(arr) => arr,226 }226 }227 }227 }228 /// Slice the value.228 /// Slice the value.239 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,239 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,240 ) -> Result<Self> {240 ) -> Result<Self> {241 match &self {241 match &self {242 IndexableVal::Str(s) => {242 Self::Str(s) => {243 let mut computed_len = None;243 let mut computed_len = None;244 let mut get_len = || {244 let mut get_len = || {245 computed_len.map_or_else(245 computed_len.map_or_else(277 .into(),277 .into(),278 ))278 ))279 }279 }280 IndexableVal::Arr(arr) => {280 Self::Arr(arr) => {281 let get_idx = |pos: Option<i32>, len: usize, default| match pos {281 let get_idx = |pos: Option<i32>, len: usize, default| match pos {282 Some(v) if v < 0 => len.saturating_sub((-v) as usize),282 Some(v) if v < 0 => len.saturating_sub((-v) as usize),283 Some(v) => (v as usize).min(len),283 Some(v) => (v as usize).min(len),307 Tree(Rc<(StrValue, StrValue, usize)>),307 Tree(Rc<(StrValue, StrValue, usize)>),308}308}309impl StrValue {309impl StrValue {310 pub fn concat(a: StrValue, b: StrValue) -> Self {310 pub fn concat(a: Self, b: Self) -> Self {311 // TODO: benchmark for an optimal value, currently just a arbitrary choice311 // TODO: benchmark for an optimal value, currently just a arbitrary choice312 const STRING_EXTEND_THRESHOLD: usize = 100;312 const STRING_EXTEND_THRESHOLD: usize = 100;313313334 }334 }335 }335 }336 match self {336 match self {337 StrValue::Flat(f) => f,337 Self::Flat(f) => f,338 StrValue::Tree(_) => {338 Self::Tree(_) => {339 let mut buf = String::with_capacity(self.len());339 let mut buf = String::with_capacity(self.len());340 write_buf(&self, &mut buf);340 write_buf(&self, &mut buf);341 buf.into()341 buf.into()344 }344 }345 pub fn len(&self) -> usize {345 pub fn len(&self) -> usize {346 match self {346 match self {347 StrValue::Flat(v) => v.len(),347 Self::Flat(v) => v.len(),348 StrValue::Tree(t) => t.2,348 Self::Tree(t) => t.2,349 }349 }350 }350 }351 pub fn is_empty(&self) -> bool {351 pub fn is_empty(&self) -> bool {367impl Display for StrValue {367impl Display for StrValue {368 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {368 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {369 match self {369 match self {370 StrValue::Flat(v) => write!(f, "{v}"),370 Self::Flat(v) => write!(f, "{v}"),371 StrValue::Tree(t) => {371 Self::Tree(t) => {372 write!(f, "{}", t.0)?;372 write!(f, "{}", t.0)?;373 write!(f, "{}", t.1)373 write!(f, "{}", t.1)374 }374 }522522523 pub fn into_indexable(self) -> Result<IndexableVal> {523 pub fn into_indexable(self) -> Result<IndexableVal> {524 Ok(match self {524 Ok(match self {525 Val::Str(s) => IndexableVal::Str(s.into_flat()),525 Self::Str(s) => IndexableVal::Str(s.into_flat()),526 Val::Arr(arr) => IndexableVal::Arr(arr),526 Self::Arr(arr) => IndexableVal::Arr(arr),527 _ => bail!(ValueIsNotIndexable(self.value_type())),527 _ => bail!(ValueIsNotIndexable(self.value_type())),528 })528 })529 }529 }crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth1use std::string::String;21use proc_macro2::TokenStream;3use proc_macro2::TokenStream;2use quote::quote;4use quote::quote;205 }207 }206}208}207209210#[allow(clippy::too_many_lines)]208fn builtin_inner(211fn builtin_inner(209 attr: BuiltinAttrs,212 attr: BuiltinAttrs,210 fun: ItemFn,213 fun: ItemFn,225 .map(|arg| ArgInfo::parse(&name, arg))228 .map(|arg| ArgInfo::parse(&name, arg))226 .collect::<Result<Vec<_>>>()?;229 .collect::<Result<Vec<_>>>()?;227230228 let params_desc = args.iter().flat_map(|a| match a {231 let params_desc = args.iter().filter_map(|a| match a {229 ArgInfo::Normal {232 ArgInfo::Normal {230 is_option,233 is_option,231 name,234 name,234 } => {237 } => {235 let name = name238 let name = name236 .as_ref()239 .as_ref()237 .map(|n| quote! {ParamName::new_static(#n)})240 .map_or_else(|| quote! {None}, |n| quote! {ParamName::new_static(#n)});238 .unwrap_or_else(|| quote! {None});239 Some(quote! {241 Some(quote! {240 #(#cfg_attrs)*242 #(#cfg_attrs)*241 BuiltinParam::new(#name, #is_option),243 BuiltinParam::new(#name, #is_option),244 ArgInfo::Lazy { is_option, name } => {246 ArgInfo::Lazy { is_option, name } => {245 let name = name247 let name = name246 .as_ref()248 .as_ref()247 .map(|n| quote! {ParamName::new_static(#n)})249 .map_or_else(|| quote! {None}, |n| quote! {ParamName::new_static(#n)});248 .unwrap_or_else(|| quote! {None});249 Some(quote! {250 Some(quote! {250 BuiltinParam::new(#name, #is_option),251 BuiltinParam::new(#name, #is_option),251 })252 })252 }253 }253 ArgInfo::Context => None,254 ArgInfo::Location => None,255 ArgInfo::This => None,254 ArgInfo::Context | ArgInfo::Location | ArgInfo::This => None,256 });255 });257256258 let mut id = 0usize;257 let mut id = 0usize;275 name,274 name,276 cfg_attrs,275 cfg_attrs,277 } => {276 } => {278 let name = name.as_ref().map(|v| v.as_str()).unwrap_or("<unnamed>");277 let name = name.as_ref().map_or("<unnamed>", String::as_str);279 let eval = quote! {jrsonnet_evaluator::State::push_description(278 let eval = quote! {jrsonnet_evaluator::State::push_description(280 || format!("argument <{}> evaluation", #name),279 || format!("argument <{}> evaluation", #name),281 || <#ty>::from_untyped(value.evaluate()?),280 || <#ty>::from_untyped(value.evaluate()?),390}389}391390392#[derive(Default)]391#[derive(Default)]392#[allow(clippy::struct_excessive_bools)]393struct TypedAttr {393struct TypedAttr {394 rename: Option<String>,394 rename: Option<String>,395 flatten: bool,395 flatten: bool,467 "this field should appear in output object, but it has no visible name",467 "this field should appear in output object, but it has no visible name",468 ));468 ));469 };469 };470 let (is_option, ty) = if let Some(ty) = extract_type_from_option(&field.ty)? {470 let (is_option, ty) = extract_type_from_option(&field.ty)?471 (true, ty.clone())471 .map_or_else(|| (false, field.ty.clone()), |ty| (true, ty.clone()));472 } else {473 (false, field.ty.clone())474 };475 if is_option && attr.flatten {472 if is_option && attr.flatten {476 if !attr.flatten_ok {473 if !attr.flatten_ok {477 return Err(Error::new(474 return Err(Error::new(551 #ident: #value,548 #ident: #value,552 }549 }553 }550 }554 fn expand_serialize(&self) -> Result<TokenStream> {551 fn expand_serialize(&self) -> TokenStream {555 let ident = &self.ident;552 let ident = &self.ident;556 let ty = &self.ty;553 let ty = &self.ty;557 Ok(if let Some(name) = self.name() {554 self.name().map_or_else(555 || {556 if self.is_option {557 quote! {558 if let Some(value) = self.#ident {559 <#ty as TypedObj>::serialize(value, out)?;560 }561 }562 } else {563 quote! {564 <#ty as TypedObj>::serialize(self.#ident, out)?;565 }566 }567 },568 |name| {558 let hide = if self.attr.hide {569 let hide = if self.attr.hide {559 quote! {.hide()}570 quote! {.hide()}560 } else {571 } else {582 .try_value(<#ty as Typed>::into_untyped(self.#ident)?)?;593 .try_value(<#ty as Typed>::into_untyped(self.#ident)?)?;583 }594 }584 }595 }585 } else if self.is_option {596 },586 quote! {587 if let Some(value) = self.#ident {588 <#ty as TypedObj>::serialize(value, out)?;589 }590 }591 } else {592 quote! {593 <#ty as TypedObj>::serialize(self.#ident, out)?;594 }595 })597 )596 }598 }597}599}598600623 let typed = {625 let typed = {624 let fields = fields626 let fields = fields625 .iter()627 .iter()626 .flat_map(TypedField::expand_field)628 .filter_map(TypedField::expand_field)627 .collect::<Vec<_>>();629 .collect::<Vec<_>>();628 quote! {630 quote! {629 impl #impl_generics Typed for #ident #ty_generics #where_clause {631 impl #impl_generics Typed for #ident #ty_generics #where_clause {650 let fields_serialize = fields652 let fields_serialize = fields651 .iter()653 .iter()652 .map(TypedField::expand_serialize)654 .map(TypedField::expand_serialize)653 .collect::<Result<Vec<_>>>()?;655 .collect::<Vec<_>>();654656655 Ok(quote! {657 Ok(quote! {656 const _: () = {658 const _: () = {767 }769 }768}770}769771770/// IStr formatting helper772/// `IStr` formatting helper771///773///772/// Using `format!("literal with no codes").into()` is slower than just `"literal with no codes".into()`774/// Using `format!("literal with no codes").into()` is slower than just `"literal with no codes".into()`773/// This macro looks for formatting codes in the input string, and uses775/// This macro looks for formatting codes in the input string, and usescrates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterbothno syntactic changes
crates/jrsonnet-stdlib/build.rsdiffbeforeafterboth26 let dest_path = Path::new(&out_dir).join("stdlib.rs");26 let dest_path = Path::new(&out_dir).join("stdlib.rs");27 let mut f = File::create(dest_path).unwrap();27 let mut f = File::create(dest_path).unwrap();28 f.write_all(28 f.write_all(29 ("#[allow(clippy::redundant_clone)]".to_owned() + &v.to_string()).as_bytes(),29 ("#[allow(clippy::redundant_clone, clippy::similar_names)]".to_owned()30 + &v.to_string())31 .as_bytes(),30 )32 )crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth9 Either, IStr, ObjValueBuilder, Result, ResultExt, Thunk, Val,9 Either, IStr, ObjValueBuilder, Result, ResultExt, Thunk, Val,10};10};111112pub(crate) fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {12pub fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {13 if let Some(on_empty) = on_empty {13 if let Some(on_empty) = on_empty {14 on_empty.evaluate()14 on_empty.evaluate()15 } else {15 } else {270 let newArrRight = arr.slice(Some(at + 1), None, None);270 let newArrRight = arr.slice(Some(at + 1), None, None);271271272 Ok(ArrValue::extended(272 Ok(ArrValue::extended(273 newArrLeft.unwrap_or(ArrValue::empty()),273 newArrLeft.unwrap_or_else(ArrValue::empty),274 newArrRight.unwrap_or(ArrValue::empty()),274 newArrRight.unwrap_or_else(ArrValue::empty),275 ))275 ))276}276}277277crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth313 settings: Rc<RefCell<Settings>>,313 settings: Rc<RefCell<Settings>>,314}314}315impl ContextInitializer {315impl ContextInitializer {316 pub fn new(_s: State, resolver: PathResolver) -> Self {316 pub fn new(s: State, resolver: PathResolver) -> Self {317 let settings = Settings {317 let settings = Settings {318 ext_vars: Default::default(),318 ext_vars: HashMap::new(),319 ext_natives: Default::default(),319 ext_natives: HashMap::new(),320 trace_printer: Box::new(StdTracePrinter::new(resolver.clone())),320 trace_printer: Box::new(StdTracePrinter::new(resolver.clone())),321 path_resolver: resolver,321 path_resolver: resolver,322 };322 };323 let settings = Rc::new(RefCell::new(settings));323 let settings = Rc::new(RefCell::new(settings));324 let stdlib_obj = stdlib_uncached(settings.clone());324 let stdlib_obj = stdlib_uncached(settings.clone());325 #[cfg(not(feature = "legacy-this-file"))]325 #[cfg(not(feature = "legacy-this-file"))]326 let stdlib_thunk = Thunk::evaluated(Val::Obj(stdlib_obj));326 let stdlib_thunk = Thunk::evaluated(Val::Obj(stdlib_obj));327 #[cfg(feature = "legacy-this-file")]328 let _ = s;327 Self {329 Self {328 #[cfg(not(feature = "legacy-this-file"))]330 #[cfg(not(feature = "legacy-this-file"))]329 context: {331 context: {330 let mut context = ContextBuilder::with_capacity(_s, 1);332 let mut context = ContextBuilder::with_capacity(s, 1);331 context.bind("std", stdlib_thunk.clone());333 context.bind("std", stdlib_thunk.clone());332 context.build()334 context.build()333 },335 },crates/jrsonnet-stdlib/src/manifest/toml.rsdiffbeforeafterboth180 options.preserve_order,180 options.preserve_order,181 ) {181 ) {182 let value = value?;182 let value = value?;183 if !is_section(&value)? {183 if is_section(&value)? {184 sections.push((key, value));185 } else {184 if !first {186 if !first {185 buf.push('\n');187 buf.push('\n');186 }188 }189 escape_key_toml_buf(&key, buf);191 escape_key_toml_buf(&key, buf);190 buf.push_str(" = ");192 buf.push_str(" = ");191 manifest_value(&value, false, buf, cur_padding, options)?;193 manifest_value(&value, false, buf, cur_padding, options)?;192 } else {194 }193 sections.push((key, value));194 }195 }195 }196 for (k, v) in sections {196 for (k, v) in sections {197 if !first {197 if !first {crates/jrsonnet-stdlib/src/math.rsdiffbeforeafterboth131}131}132132133#[builtin]133#[builtin]134#[allow(clippy::float_cmp)]134pub fn builtin_is_odd(x: f64) -> bool {135pub fn builtin_is_odd(x: f64) -> bool {135 builtin_round(x) % 2.0 == 1.0136 builtin_round(x) % 2.0 == 1.0136}137}137138138#[builtin]139#[builtin]140#[allow(clippy::float_cmp)]139pub fn builtin_is_integer(x: f64) -> bool {141pub fn builtin_is_integer(x: f64) -> bool {140 builtin_round(x) == x142 builtin_round(x) == x141}143}142144143#[builtin]145#[builtin]146#[allow(clippy::float_cmp)]144pub fn builtin_is_decimal(x: f64) -> bool {147pub fn builtin_is_decimal(x: f64) -> bool {145 builtin_round(x) != x148 builtin_round(x) != x146}149}crates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth67 v => v.manifest(JsonFormat::debug())?.into(),67 v => v.manifest(JsonFormat::debug())?.into(),68 },68 },69 );69 );70 if let Some(rest) = rest {70 rest.map_or_else(|| Ok(str), |rest| rest.evaluate())71 rest.evaluate()72 } else {73 Ok(str)74 }75}71}767277#[allow(clippy::comparison_chain)]73#[allow(clippy::comparison_chain)]82 (Either2::B(a), Either2::B(b)) => {78 (Either2::B(a), Either2::B(b)) => {83 if b.len() > a.len() {79 if b.len() > a.len() {84 return Ok(false);80 return Ok(false);85 } else if b.len() == a.len() {81 } else if b.len() == a.len() {86 return equals(&Val::Arr(a), &Val::Arr(b));82 return equals(&Val::Arr(a), &Val::Arr(b));87 } else {83 }88 for (a, b) in a.iter().take(b.len()).zip(b.iter()) {84 for (a, b) in a.iter().take(b.len()).zip(b.iter()) {89 let a = a?;85 let a = a?;90 let b = b?;86 let b = b?;93 }89 }94 }90 }95 true91 true96 }97 }92 }98 _ => bail!("both arguments should be of the same type"),93 _ => bail!("both arguments should be of the same type"),99 })94 })107 (Either2::B(a), Either2::B(b)) => {102 (Either2::B(a), Either2::B(b)) => {108 if b.len() > a.len() {103 if b.len() > a.len() {109 return Ok(false);104 return Ok(false);110 } else if b.len() == a.len() {105 } else if b.len() == a.len() {111 return equals(&Val::Arr(a), &Val::Arr(b));106 return equals(&Val::Arr(a), &Val::Arr(b));112 } else {107 }113 let a_len = a.len();108 let a_len = a.len();114 for (a, b) in a.iter().skip(a_len - b.len()).zip(b.iter()) {109 for (a, b) in a.iter().skip(a_len - b.len()).zip(b.iter()) {115 let a = a?;110 let a = a?;119 }114 }120 }115 }121 true116 true122 }123 }117 }124 _ => bail!("both arguments should be of the same type"),118 _ => bail!("both arguments should be of the same type"),125 })119 })crates/jrsonnet-stdlib/src/objects.rsdiffbeforeafterboth155 if k == key {155 if k == key {156 continue;156 continue;157 }157 }158 new_obj.field(k).value(v.unwrap())158 new_obj.field(k).value(v.unwrap());159 }159 }160160161 new_obj.build()161 new_obj.build()crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth363637fn get_sort_type<T>(values: &[T], key_getter: impl Fn(&T) -> &Val) -> Result<SortKeyType> {37fn get_sort_type<T>(values: &[T], key_getter: impl Fn(&T) -> &Val) -> Result<SortKeyType> {38 let mut sort_type = SortKeyType::Unknown;38 let mut sort_type = SortKeyType::Unknown;39 for i in values.iter() {39 for i in values {40 let i = key_getter(i);40 let i = key_getter(i);41 match (i, sort_type) {41 match (i, sort_type) {42 (Val::Str(_), SortKeyType::Unknown) => sort_type = SortKeyType::String,42 (Val::Str(_), SortKeyType::Unknown) => sort_type = SortKeyType::String,crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth75 .enumerate()75 .enumerate()76 {76 {77 if &strb[i..i + pat.len()] == pat {77 if &strb[i..i + pat.len()] == pat {78 out.push(Val::Num(ch_idx as f64))78 out.push(Val::Num(ch_idx as f64));79 }79 }80 }80 }81 out.into()81 out.into()117}117}118118119fn parse_nat<const BASE: u32>(raw: &str) -> Result<f64> {119fn parse_nat<const BASE: u32>(raw: &str) -> Result<f64> {120 debug_assert!(121 1 <= BASE && BASE <= 16,122 "integer base should be between 1 and 16"123 );124125 const ZERO_CODE: u32 = '0' as u32;120 const ZERO_CODE: u32 = '0' as u32;126 const UPPER_A_CODE: u32 = 'A' as u32;121 const UPPER_A_CODE: u32 = 'A' as u32;135 }130 }136 }131 }132133 debug_assert!(134 1 <= BASE && BASE <= 16,135 "integer base should be between 1 and 16"136 );137137138 let base = BASE as f64;138 let base = f64::from(BASE);139139140 raw.chars().try_fold(0f64, |aggregate, digit| {140 raw.chars().try_fold(0f64, |aggregate, digit| {141 let digit = digit as u32;141 let digit = digit as u32;142 // if-let-else looks better here than Option combinators143 #[allow(clippy::option_if_let_else)]142 let digit = if let Some(digit) = checked_sub_if(BASE > 10, digit, LOWER_A_CODE) {144 let digit = if let Some(digit) = checked_sub_if(BASE > 10, digit, LOWER_A_CODE) {143 digit + 10145 digit + 10144 } else if let Some(digit) = checked_sub_if(BASE > 10, digit, UPPER_A_CODE) {146 } else if let Some(digit) = checked_sub_if(BASE > 10, digit, UPPER_A_CODE) {148 };150 };149151150 if digit < BASE {152 if digit < BASE {151 Ok(base * aggregate + digit as f64)153 Ok(base.mul_add(aggregate, f64::from(digit)))152 } else {154 } else {153 bail!("{raw:?} is not a base {BASE} integer");155 bail!("{raw:?} is not a base {BASE} integer");154 }156 }crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth166166167fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {167fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {168 if *a == ComplexValType::Any {168 if *a == ComplexValType::Any {169 write!(f, "array")?169 write!(f, "array")?;170 } else {170 } else {171 write!(f, "Array<{a}>")?171 write!(f, "Array<{a}>")?;172 }172 }173 Ok(())173 Ok(())174}174}175175176impl Display for ComplexValType {176impl Display for ComplexValType {177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {178 match self {178 match self {179 ComplexValType::Any => write!(f, "any")?,179 Self::Any => write!(f, "any")?,180 ComplexValType::Simple(s) => write!(f, "{s}")?,180 Self::Simple(s) => write!(f, "{s}")?,181 ComplexValType::Char => write!(f, "char")?,181 Self::Char => write!(f, "char")?,182 ComplexValType::BoundedNumber(a, b) => write!(182 Self::BoundedNumber(a, b) => write!(183 f,183 f,184 "BoundedNumber<{}, {}>",184 "BoundedNumber<{}, {}>",185 a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),185 a.map(|e| e.to_string())186 .unwrap_or_else(|| "open".to_owned()),186 b.map(|e| e.to_string()).unwrap_or_else(|| "".into())187 b.map(|e| e.to_string())188 .unwrap_or_else(|| "open".to_owned())187 )?,189 )?,188 ComplexValType::ArrayRef(a) => print_array(a, f)?,190 Self::ArrayRef(a) => print_array(a, f)?,189 ComplexValType::Array(a) => print_array(a, f)?,191 Self::Array(a) => print_array(a, f)?,190 ComplexValType::ObjectRef(fields) => {192 Self::ObjectRef(fields) => {191 write!(f, "{{")?;193 write!(f, "{{")?;192 for (i, (k, v)) in fields.iter().enumerate() {194 for (i, (k, v)) in fields.iter().enumerate() {193 if i != 0 {195 if i != 0 {197 }199 }198 write!(f, "}}")?;200 write!(f, "}}")?;199 }201 }200 ComplexValType::AttrsOf(a) => {202 Self::AttrsOf(a) => {201 if matches!(a, ComplexValType::Any) {203 if matches!(a, Self::Any) {202 write!(f, "object")?;204 write!(f, "object")?;203 } else {205 } else {204 write!(f, "AttrsOf<{a}>")?;206 write!(f, "AttrsOf<{a}>")?;205 }207 }206 }208 }207 ComplexValType::Union(v) => write_union(f, true, v.iter())?,209 Self::Union(v) => write_union(f, true, v.iter())?,208 ComplexValType::UnionRef(v) => write_union(f, true, v.iter().copied())?,210 Self::UnionRef(v) => write_union(f, true, v.iter().copied())?,209 ComplexValType::Sum(v) => write_union(f, false, v.iter())?,211 Self::Sum(v) => write_union(f, false, v.iter())?,210 ComplexValType::SumRef(v) => write_union(f, false, v.iter().copied())?,212 Self::SumRef(v) => write_union(f, false, v.iter().copied())?,211 ComplexValType::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,213 Self::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,212 };214 };213 Ok(())215 Ok(())214 }216 }tests/suite/std_param_names.jsonnetdiffbeforeafterboth49 min: ['a', 'b'],49 min: ['a', 'b'],50 clamp: ['x', 'minVal', 'maxVal'],50 clamp: ['x', 'minVal', 'maxVal'],51 flattenArrays: ['arrs'],51 flattenArrays: ['arrs'],52 flattenDeepArray: ['value'],52 manifestIni: ['ini'],53 manifestIni: ['ini'],53 manifestToml: ['value'],54 manifestToml: ['value'],54 manifestTomlEx: ['value', 'indent'],55 manifestTomlEx: ['value', 'indent'],