git.delta.rocks / jrsonnet / refs/commits / a05afd32cebc

difftreelog

style fix clippy warnings

Yaroslav Bolyukin2023-01-20parent: #974f2c1.patch.diff
in: master

16 files changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
before · cmds/jrsonnet/src/main.rs
1use std::{2	fs::{create_dir_all, File},3	io::{Read, Write},4};56use clap::{CommandFactory, Parser};7use clap_complete::Shell;8use jrsonnet_cli::{ManifestOpts, OutputOpts, TraceOpts, MiscOpts, TlaOpts, StdOpts, GcOpts};9use jrsonnet_evaluator::{10	apply_tla,11	error::{Error as JrError, ErrorKind},12	throw, ResultExt, State, Val,13};1415#[cfg(feature = "mimalloc")]16#[global_allocator]17static GLOBAL: mimallocator::Mimalloc = mimallocator::Mimalloc;1819#[derive(Parser)]20enum SubOpts {21	/// Generate completions for specified shell22	Generate {23		/// Target shell name24		shell: Shell,25	},26}2728#[derive(Parser)]29#[clap(next_help_heading = "DEBUG")]30struct DebugOpts {31	/// Required OS stack size.32	/// This shouldn't be changed unless jrsonnet is failing with stack overflow error.33	#[clap(long, name = "size")]34	pub os_stack: Option<usize>,35}3637#[derive(Parser)]38#[clap(next_help_heading = "INPUT")]39struct InputOpts {40	/// Treat input as code, evaluate them instead of reading file41	#[clap(long, short = 'e')]42	pub exec: bool,4344	/// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself45	pub input: Option<String>,46}4748/// Jsonnet commandline interpreter (Rust implementation)49#[derive(Parser)]50#[clap(51	args_conflicts_with_subcommands = true,52	disable_version_flag = true,53	version,54	author55)]56struct Opts {57	#[clap(subcommand)]58	sub: Option<SubOpts>,5960	#[clap(flatten)]61	input: InputOpts,62	#[clap(flatten)]63	misc: MiscOpts,64	#[clap(flatten)]65	tla: TlaOpts,66	#[clap(flatten)]67	std: StdOpts,68	#[clap(flatten)]69	gc: GcOpts,7071	#[clap(flatten)]72	trace: TraceOpts,73	#[clap(flatten)]74	manifest: ManifestOpts,75	#[clap(flatten)]76	output: OutputOpts,77	#[clap(flatten)]78	debug: DebugOpts,79}8081fn main() {82	let opts: Opts = Opts::parse();8384	if let Some(sub) = opts.sub {85		match sub {86			SubOpts::Generate { shell } => {87				use clap_complete::generate;88				let app = &mut Opts::command();89				let buf = &mut std::io::stdout();90				generate(shell, app, "jrsonnet", buf);91				std::process::exit(0)92			}93		}94	}9596	let success = if let Some(size) = opts.debug.os_stack {97		std::thread::Builder::new()98			.stack_size(size * 1024 * 1024)99			.spawn(|| main_catch(opts))100			.expect("new thread spawned")101			.join()102			.expect("thread finished successfully")103	} else {104		main_catch(opts)105	};106	if !success {107		std::process::exit(1);108	}109}110111#[derive(thiserror::Error, Debug)]112enum Error {113	// Handled differently114	#[error("evaluation error")]115	Evaluation(JrError),116	#[error("io error")]117	Io(#[from] std::io::Error),118	#[error("input is not utf8 encoded")]119	Utf8(#[from] std::str::Utf8Error),120	#[error("missing input argument")]121	MissingInputArgument,122}123impl From<JrError> for Error {124	fn from(e: JrError) -> Self {125		Self::Evaluation(e)126	}127}128impl From<ErrorKind> for Error {129	fn from(e: ErrorKind) -> Self {130		Self::from(JrError::from(e))131	}132}133134fn main_catch(opts: Opts) -> bool {135	let s = State::default();136	let trace = opts137		.trace138		.trace_format();139	if let Err(e) = main_real(&s, opts) {140		if let Error::Evaluation(e) = e {141			let mut out = String::new();142			trace.write_trace(&mut out, &e).expect("format error");143			eprintln!("{out}")144		} else {145			eprintln!("{}", e);146		}147		return false;148	}149	true150}151152fn main_real(s: &State, opts: Opts) -> Result<(), Error> {153	let _gc_leak_guard= opts.gc.leak_on_exit();154	let _gc_print_stats = opts.gc.stats_printer();155	let _stack_depth_override = opts.misc.stack_size_override();156157	let import_resolver = opts.misc.import_resolver();158	s.set_import_resolver(import_resolver);159160	let std = opts.std.context_initializer(s)?;161	if let Some(std) = std {162		s.set_context_initializer(std);163	}164165	let input = opts.input.input.ok_or(Error::MissingInputArgument)?;166	let val = if opts.input.exec {167		s.evaluate_snippet("<cmdline>".to_owned(), &input as &str)?168	} else if input == "-" {169		let mut input = Vec::new();170		std::io::stdin().read_to_end(&mut input)?;171		let input_str = std::str::from_utf8(&input)?;172		s.evaluate_snippet("<stdin>".to_owned(), input_str)?173	} else {174		s.import(&input)?175	};176177	let tla = opts.tla.tla_opts()?;178	let val = apply_tla(s.clone(), &tla, val)?;179180	let manifest_format = opts.manifest.manifest_format();181	if let Some(multi) = opts.output.multi {182		if opts.output.create_output_dirs {183			let mut dir = multi.clone();184			dir.pop();185			create_dir_all(dir)?;186		}187		let Val::Obj(obj) = val else {188			throw!("value should be object for --multi manifest, got {}", val.value_type())189		};190		for (field, data) in obj.iter(191			#[cfg(feature = "exp-preserve-order")]192			opts.manifest.preserve_order,193		) {194			let data = data.with_description(|| format!("getting field {field} for manifest"))?;195196			let mut path = multi.clone();197			path.push(&field as &str);198			if opts.output.create_output_dirs {199				let mut dir = path.clone();200				dir.pop();201				create_dir_all(dir)?;202			}203			println!("{}", path.to_str().expect("path"));204			let mut file = File::create(path)?;205			writeln!(206				file,207				"{}",208				data.manifest(&manifest_format)209					.with_description(|| format!("manifesting {field}"))?210			)?;211		}212	} else if let Some(path) = opts.output.output_file {213		if opts.output.create_output_dirs {214			let mut dir = path.clone();215			dir.pop();216			create_dir_all(dir)?;217		}218		let mut file = File::create(path)?;219		writeln!(file, "{}", val.manifest(manifest_format)?)?;220	} else {221		let output = val.manifest(manifest_format)?;222		if !output.is_empty() {223			println!("{}", output);224		}225	}226227	Ok(())228}
after · cmds/jrsonnet/src/main.rs
1use std::{2	fs::{create_dir_all, File},3	io::{Read, Write},4};56use clap::{CommandFactory, Parser};7use clap_complete::Shell;8use jrsonnet_cli::{GcOpts, ManifestOpts, MiscOpts, OutputOpts, StdOpts, TlaOpts, TraceOpts};9use jrsonnet_evaluator::{10	apply_tla,11	error::{Error as JrError, ErrorKind},12	throw, ResultExt, State, Val,13};1415#[cfg(feature = "mimalloc")]16#[global_allocator]17static GLOBAL: mimallocator::Mimalloc = mimallocator::Mimalloc;1819#[derive(Parser)]20enum SubOpts {21	/// Generate completions for specified shell22	Generate {23		/// Target shell name24		shell: Shell,25	},26}2728#[derive(Parser)]29#[clap(next_help_heading = "DEBUG")]30struct DebugOpts {31	/// Required OS stack size.32	/// This shouldn't be changed unless jrsonnet is failing with stack overflow error.33	#[clap(long, name = "size")]34	pub os_stack: Option<usize>,35}3637#[derive(Parser)]38#[clap(next_help_heading = "INPUT")]39struct InputOpts {40	/// Treat input as code, evaluate them instead of reading file41	#[clap(long, short = 'e')]42	pub exec: bool,4344	/// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself45	pub input: Option<String>,46}4748/// Jsonnet commandline interpreter (Rust implementation)49#[derive(Parser)]50#[clap(51	args_conflicts_with_subcommands = true,52	disable_version_flag = true,53	version,54	author55)]56struct Opts {57	#[clap(subcommand)]58	sub: Option<SubOpts>,5960	#[clap(flatten)]61	input: InputOpts,62	#[clap(flatten)]63	misc: MiscOpts,64	#[clap(flatten)]65	tla: TlaOpts,66	#[clap(flatten)]67	std: StdOpts,68	#[clap(flatten)]69	gc: GcOpts,7071	#[clap(flatten)]72	trace: TraceOpts,73	#[clap(flatten)]74	manifest: ManifestOpts,75	#[clap(flatten)]76	output: OutputOpts,77	#[clap(flatten)]78	debug: DebugOpts,79}8081fn main() {82	let opts: Opts = Opts::parse();8384	if let Some(sub) = opts.sub {85		match sub {86			SubOpts::Generate { shell } => {87				use clap_complete::generate;88				let app = &mut Opts::command();89				let buf = &mut std::io::stdout();90				generate(shell, app, "jrsonnet", buf);91				std::process::exit(0)92			}93		}94	}9596	let success = if let Some(size) = opts.debug.os_stack {97		std::thread::Builder::new()98			.stack_size(size * 1024 * 1024)99			.spawn(|| main_catch(opts))100			.expect("new thread spawned")101			.join()102			.expect("thread finished successfully")103	} else {104		main_catch(opts)105	};106	if !success {107		std::process::exit(1);108	}109}110111#[derive(thiserror::Error, Debug)]112enum Error {113	// Handled differently114	#[error("evaluation error")]115	Evaluation(JrError),116	#[error("io error")]117	Io(#[from] std::io::Error),118	#[error("input is not utf8 encoded")]119	Utf8(#[from] std::str::Utf8Error),120	#[error("missing input argument")]121	MissingInputArgument,122}123impl From<JrError> for Error {124	fn from(e: JrError) -> Self {125		Self::Evaluation(e)126	}127}128impl From<ErrorKind> for Error {129	fn from(e: ErrorKind) -> Self {130		Self::from(JrError::from(e))131	}132}133134fn main_catch(opts: Opts) -> bool {135	let s = State::default();136	let trace = opts.trace.trace_format();137	if let Err(e) = main_real(&s, opts) {138		if let Error::Evaluation(e) = e {139			let mut out = String::new();140			trace.write_trace(&mut out, &e).expect("format error");141			eprintln!("{out}")142		} else {143			eprintln!("{e}");144		}145		return false;146	}147	true148}149150fn main_real(s: &State, opts: Opts) -> Result<(), Error> {151	let _gc_leak_guard = opts.gc.leak_on_exit();152	let _gc_print_stats = opts.gc.stats_printer();153	let _stack_depth_override = opts.misc.stack_size_override();154155	let import_resolver = opts.misc.import_resolver();156	s.set_import_resolver(import_resolver);157158	let std = opts.std.context_initializer(s)?;159	if let Some(std) = std {160		s.set_context_initializer(std);161	}162163	let input = opts.input.input.ok_or(Error::MissingInputArgument)?;164	let val = if opts.input.exec {165		s.evaluate_snippet("<cmdline>".to_owned(), &input as &str)?166	} else if input == "-" {167		let mut input = Vec::new();168		std::io::stdin().read_to_end(&mut input)?;169		let input_str = std::str::from_utf8(&input)?;170		s.evaluate_snippet("<stdin>".to_owned(), input_str)?171	} else {172		s.import(&input)?173	};174175	let tla = opts.tla.tla_opts()?;176	let val = apply_tla(s.clone(), &tla, val)?;177178	let manifest_format = opts.manifest.manifest_format();179	if let Some(multi) = opts.output.multi {180		if opts.output.create_output_dirs {181			let mut dir = multi.clone();182			dir.pop();183			create_dir_all(dir)?;184		}185		let Val::Obj(obj) = val else {186			throw!("value should be object for --multi manifest, got {}", val.value_type())187		};188		for (field, data) in obj.iter(189			#[cfg(feature = "exp-preserve-order")]190			opts.manifest.preserve_order,191		) {192			let data = data.with_description(|| format!("getting field {field} for manifest"))?;193194			let mut path = multi.clone();195			path.push(&field as &str);196			if opts.output.create_output_dirs {197				let mut dir = path.clone();198				dir.pop();199				create_dir_all(dir)?;200			}201			println!("{}", path.to_str().expect("path"));202			let mut file = File::create(path)?;203			writeln!(204				file,205				"{}",206				data.manifest(&manifest_format)207					.with_description(|| format!("manifesting {field}"))?208			)?;209		}210	} else if let Some(path) = opts.output.output_file {211		if opts.output.create_output_dirs {212			let mut dir = path.clone();213			dir.pop();214			create_dir_all(dir)?;215		}216		let mut file = File::create(path)?;217		writeln!(file, "{}", val.manifest(manifest_format)?)?;218	} else {219		let output = val.manifest(manifest_format)?;220		if !output.is_empty() {221			println!("{output}");222		}223	}224225	Ok(())226}
modifiedcrates/jrsonnet-cli/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/lib.rs
+++ b/crates/jrsonnet-cli/src/lib.rs
@@ -6,7 +6,10 @@
 use std::{env, marker::PhantomData, path::PathBuf};
 
 use clap::Parser;
-use jrsonnet_evaluator::{error::Result, stack::{set_stack_depth_limit, StackDepthLimitOverrideGuard, limit_stack_depth}, FileImportResolver, State, ImportResolver};
+use jrsonnet_evaluator::{
+	stack::{limit_stack_depth, StackDepthLimitOverrideGuard},
+	FileImportResolver,
+};
 use jrsonnet_gcmodule::with_thread_object_space;
 pub use manifest::*;
 pub use stdlib::*;
@@ -71,6 +74,7 @@
 }
 impl GcOpts {
 	pub fn stats_printer(&self) -> Option<GcStatsPrinter> {
+		#[allow(clippy::unnecessary_lazy_evaluations/*, reason = "GcStatsPrinter has side-effect on Drop"*/)]
 		self.gc_print_stats.then(|| GcStatsPrinter {
 			collect_before_printing_stats: self.gc_collect_before_printing_stats,
 		})
@@ -96,7 +100,7 @@
 		eprintln!("=== GC STATS ===");
 		if self.collect_before_printing_stats {
 			let collected = jrsonnet_gcmodule::collect_thread_cycles();
-			eprintln!("Collected: {}", collected);
+			eprintln!("Collected: {collected}");
 		}
 		eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked())
 	}
modifiedcrates/jrsonnet-cli/src/manifest.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/manifest.rs
+++ b/crates/jrsonnet-cli/src/manifest.rs
@@ -1,10 +1,8 @@
 use std::path::PathBuf;
 
 use clap::{Parser, ValueEnum};
-use jrsonnet_evaluator::{
-	error::Result,
-	manifest::{JsonFormat, ManifestFormat, StringFormat, ToStringFormat, YamlStreamFormat},
-	State,
+use jrsonnet_evaluator::manifest::{
+	JsonFormat, ManifestFormat, StringFormat, ToStringFormat, YamlStreamFormat,
 };
 use jrsonnet_stdlib::{TomlFormat, YamlFormat};
 
modifiedcrates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/stdlib.rs
+++ b/crates/jrsonnet-cli/src/stdlib.rs
@@ -1,7 +1,7 @@
 use std::{fs::read_to_string, str::FromStr};
 
 use clap::Parser;
-use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};
+use jrsonnet_evaluator::{error::Result, trace::PathResolver, State};
 use jrsonnet_stdlib::ContextInitializer;
 
 #[derive(Clone)]
@@ -49,7 +49,7 @@
 				name: out[0].into(),
 				value: content,
 			}),
-			Err(e) => Err(format!("{}", e)),
+			Err(e) => Err(format!("{e}")),
 		}
 	}
 }
@@ -86,8 +86,7 @@
 		if self.no_stdlib {
 			return Ok(None);
 		}
-		let ctx =
-			ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
+		let ctx = ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
 		for ext in self.ext_str.iter() {
 			ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
 		}
modifiedcrates/jrsonnet-cli/src/tla.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/tla.rs
+++ b/crates/jrsonnet-cli/src/tla.rs
@@ -3,7 +3,7 @@
 	error::{ErrorKind, Result},
 	function::TlaArg,
 	gc::GcHashMap,
-	IStr, State,
+	IStr,
 };
 use jrsonnet_parser::{ParserSettings, Source};
 
modifiedcrates/jrsonnet-cli/src/trace.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/trace.rs
+++ b/crates/jrsonnet-cli/src/trace.rs
@@ -1,9 +1,5 @@
 use clap::{Parser, ValueEnum};
-use jrsonnet_evaluator::{
-	error::Result,
-	trace::{CompactFormat, ExplainingFormat, PathResolver, TraceFormat},
-	State,
-};
+use jrsonnet_evaluator::trace::{CompactFormat, ExplainingFormat, PathResolver, TraceFormat};
 
 #[derive(PartialEq, Eq, ValueEnum, Clone)]
 pub enum TraceFormatName {
modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -274,6 +274,7 @@
 		f.debug_tuple("LocError").field(&self.0).finish()
 	}
 }
+impl std::error::Error for Error {}
 
 pub trait ErrorSource {
 	fn to_location(self) -> Option<ExprLocation>;
modifiedcrates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -104,28 +104,15 @@
 					}
 				}
 			} else {
-				{
-					let ai = a.iter();
-					let bi = b.iter();
+				let ai = a.iter();
+				let bi = b.iter();
 
-					for (a, b) in ai.zip(bi) {
-						let ord = evaluate_compare_op(&a?, &b?, op)?;
-						if !ord.is_eq() {
-							return Ok(ord);
-						}
+				for (a, b) in ai.zip(bi) {
+					let ord = evaluate_compare_op(&a?, &b?, op)?;
+					if !ord.is_eq() {
+						return Ok(ord);
 					}
 				}
-				// {
-				// 	let ai = a.iter_expl();
-				// 	let bi = b.iter_expl();
-
-				// 	for (a, b) in ai.zip(bi) {
-				// 		let ord = evaluate_compare_op(&a?, &b?, op)?;
-				// 		if !ord.is_eq() {
-				// 			return Ok(ord);
-				// 		}
-				// 	}
-				// }
 			}
 			a.len().cmp(&b.len())
 		}
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -36,6 +36,7 @@
 	clippy::use_self,
 	// https://github.com/rust-lang/rust-clippy/issues/8539
 	clippy::iter_with_drain,
+	clippy::type_repetition_in_bounds,
 	// ci is being run with nightly, but library should work on stable
 	clippy::missing_const_for_fn,
 )]
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/obj.rs
+++ b/crates/jrsonnet-evaluator/src/obj.rs
@@ -54,7 +54,7 @@
 
 #[cfg(feature = "exp-preserve-order")]
 mod ordering {
-	use std::cmp::Reverse;
+	use std::cmp::{Ordering, Reverse};
 
 	use jrsonnet_gcmodule::Trace;
 
@@ -81,12 +81,10 @@
 			Self(Reverse(depth), index)
 		}
 		pub fn collide(self, other: Self) -> Self {
-			if self.0 .0 > other.0 .0 {
-				self
-			} else if self.0 .0 < other.0 .0 {
-				other
-			} else {
-				unreachable!("object can't have two fields with same name")
+			match self.0 .0.cmp(&other.0 .0) {
+				Ordering::Greater => self,
+				Ordering::Less => other,
+				Ordering::Equal => unreachable!("object can't have two fields with the same name"),
 			}
 		}
 	}
@@ -188,6 +186,12 @@
 	pub fn new_empty() -> Self {
 		Self::new(None, Cc::new(GcHashMap::new()), Cc::new(Vec::new()))
 	}
+	pub fn builder() -> ObjValueBuilder {
+		ObjValueBuilder::new()
+	}
+	pub fn builder_with_capacity(capacity: usize) -> ObjValueBuilder {
+		ObjValueBuilder::with_capacity(capacity)
+	}
 	#[must_use]
 	pub fn extend_from(&self, sup: Self) -> Self {
 		match &self.0.sup {
@@ -304,7 +308,7 @@
 						break;
 					}
 					fields[j] = fields[k].clone();
-					j = k
+					j = k;
 				}
 				fields[j] = x;
 			}
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -33,6 +33,7 @@
 	Pending,
 }
 
+/// Lazily evaluated value
 #[allow(clippy::module_name_repetitions)]
 #[derive(Clone, Trace)]
 pub struct Thunk<T: Trace>(Cc<RefCell<ThunkInner<T>>>);
@@ -57,6 +58,13 @@
 		self.evaluate()?;
 		Ok(())
 	}
+
+	/// Evaluate thunk, or return cached value
+	///
+	/// # Errors
+	///
+	/// - Lazy value evaluation returned error
+	/// - This method was called during inner value evaluation
 	pub fn evaluate(&self) -> Result<T> {
 		match &*self.0.borrow() {
 			ThunkInner::Computed(v) => return Ok(v.clone()),
@@ -132,7 +140,7 @@
 	}
 }
 
-/// Represents a Jsonnet value, which can be spliced or indexed (string or array).
+/// Represents a Jsonnet value, which can be sliced or indexed (string or array).
 #[allow(clippy::module_name_repetitions)]
 pub enum IndexableVal {
 	/// String.
@@ -247,6 +255,16 @@
 		}
 	}
 }
+impl From<&str> for StrValue {
+	fn from(value: &str) -> Self {
+		Self::Flat(value.into())
+	}
+}
+impl From<String> for StrValue {
+	fn from(value: String) -> Self {
+		Self::Flat(value.into())
+	}
+}
 impl Display for StrValue {
 	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 		match self {
modifiedcrates/jrsonnet-parser/src/source.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/source.rs
+++ b/crates/jrsonnet-parser/src/source.rs
@@ -33,8 +33,8 @@
 		}
 		fn dyn_eq(&self, other: &dyn $T) -> bool {
 			let Some(other) = other.as_any().downcast_ref::<Self>() else {
-												return false
-											};
+				return false
+			};
 			let this = <Self as $T>::as_any(self)
 				.downcast_ref::<Self>()
 				.expect("restricted by impl");
modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -211,7 +211,7 @@
 				locs[0].line
 			);
 		}
-		eprintln!(" {}", value);
+		eprintln!(" {value}");
 	}
 }
 
@@ -229,7 +229,7 @@
 }
 
 fn extvar_source(name: &str, code: impl Into<IStr>) -> Source {
-	let source_name = format!("<extvar:{}>", name);
+	let source_name = format!("<extvar:{name}>");
 	Source::new_virtual(source_name.into(), code.into())
 }
 
modifiedcrates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/misc.rs
+++ b/crates/jrsonnet-stdlib/src/misc.rs
@@ -46,7 +46,7 @@
 		.ext_natives
 		.get(&x)
 		.cloned()
-		.map_or(Val::Null, |v| Val::Func(FuncVal::Builtin(v.clone())))
+		.map_or(Val::Null, |v| Val::Func(FuncVal::Builtin(v)))
 }
 
 #[builtin(fields(
modifiedcrates/jrsonnet-stdlib/src/parse.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/parse.rs
+++ b/crates/jrsonnet-stdlib/src/parse.rs
@@ -8,7 +8,7 @@
 #[builtin]
 pub fn builtin_parse_json(str: IStr) -> Result<Val> {
 	let value: Val = serde_json::from_str(&str)
-		.map_err(|e| RuntimeError(format!("failed to parse json: {}", e).into()))?;
+		.map_err(|e| RuntimeError(format!("failed to parse json: {e}").into()))?;
 	Ok(value)
 }
 
@@ -22,7 +22,7 @@
 	let mut out = vec![];
 	for item in value {
 		let val = Val::deserialize(item)
-			.map_err(|e| RuntimeError(format!("failed to parse yaml: {}", e).into()))?;
+			.map_err(|e| RuntimeError(format!("failed to parse yaml: {e}").into()))?;
 		out.push(val);
 	}
 	Ok(if out.is_empty() {
modifiedcrates/jrsonnet-types/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -150,7 +150,7 @@
 		if should_add_braces {
 			write!(f, "(")?;
 		}
-		write!(f, "{}", v)?;
+		write!(f, "{v}")?;
 		if should_add_braces {
 			write!(f, ")")?;
 		}
@@ -162,7 +162,7 @@
 	if *a == ComplexValType::Any {
 		write!(f, "array")?
 	} else {
-		write!(f, "Array<{}>", a)?
+		write!(f, "Array<{a}>")?
 	}
 	Ok(())
 }
@@ -171,7 +171,7 @@
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		match self {
 			ComplexValType::Any => write!(f, "any")?,
-			ComplexValType::Simple(s) => write!(f, "{}", s)?,
+			ComplexValType::Simple(s) => write!(f, "{s}")?,
 			ComplexValType::Char => write!(f, "char")?,
 			ComplexValType::BoundedNumber(a, b) => write!(
 				f,
@@ -187,7 +187,7 @@
 					if i != 0 {
 						write!(f, ", ")?;
 					}
-					write!(f, "{}: {}", k, v)?;
+					write!(f, "{k}: {v}")?;
 				}
 				write!(f, "}}")?;
 			}