git.delta.rocks / jrsonnet / refs/commits / 1ddb92c00d0f

difftreelog

style fix clippy warnings

ntlrsvsuYaroslav Bolyukin2026-03-22parent: #f0c8338.patch.diff
in: master

24 files changed

modifiedCargo.lockdiffbeforeafterboth
676676
677[[package]]677[[package]]
678name = "jrsonnet-gcmodule"678name = "jrsonnet-gcmodule"
679version = "0.4.1"679version = "0.4.2"
680source = "registry+https://github.com/rust-lang/crates.io-index"680source = "registry+https://github.com/rust-lang/crates.io-index"
681checksum = "c33f4f6cdc60f5ae94ebae3dfe7f484ae79b364225d9b19601b24c804cfd8751"681checksum = "f95b976a79e4000bb9e07ff0709dca0ea27bcf1952d4c17d91fb7364d6145683"
682dependencies = [682dependencies = [
683 "jrsonnet-gcmodule-derive",683 "jrsonnet-gcmodule-derive",
684]684]
685685
686[[package]]686[[package]]
687name = "jrsonnet-gcmodule-derive"687name = "jrsonnet-gcmodule-derive"
688version = "0.4.1"688version = "0.4.2"
689source = "registry+https://github.com/rust-lang/crates.io-index"689source = "registry+https://github.com/rust-lang/crates.io-index"
690checksum = "2b30c95b285f9bb6709f1b3e6fc69b3a25e39b32ff987587fd108f0f22be5fa3"690checksum = "51d928626220a310ff0cec815e80cf7fe104697184352ca21c40534e0b0d72d9"
691dependencies = [691dependencies = [
692 "proc-macro2",692 "proc-macro2",
693 "quote",693 "quote",
1602source = "registry+https://github.com/rust-lang/crates.io-index"1602source = "registry+https://github.com/rust-lang/crates.io-index"
1603checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"1603checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
1604dependencies = [1604dependencies = [
1605 "windows-sys 0.59.0",1605 "windows-sys 0.61.2",
1606]1606]
16071607
1608[[package]]1608[[package]]
modifiedCargo.tomldiffbeforeafterboth
20jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre97" }20jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre97" }
21jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre97" }21jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre97" }
22jrsonnet-formatter = { path = "./crates/jrsonnet-formatter", version = "0.5.0-pre97" }22jrsonnet-formatter = { path = "./crates/jrsonnet-formatter", version = "0.5.0-pre97" }
23jrsonnet-gcmodule = { version = "0.4.1" }23jrsonnet-gcmodule = { version = "0.4.2" }
24# Diagnostics.24# Diagnostics.
25# hi-doc is my library, which handles text formatting very well, but isn't polished enough yet25# hi-doc is my library, which handles text formatting very well, but isn't polished enough yet
26# Previous implementation was based on annotate-snippets, which I don't like for many reasons.26# Previous implementation was based on annotate-snippets, which I don't like for many reasons.
modifiedbindings/jsonnet/src/import.rsdiffbeforeafterboth
66 base.as_ptr(),66 base.as_ptr(),
67 rel.as_ptr(),67 rel.as_ptr(),
68 &mut found_here.cast_const(),68 &mut found_here.cast_const(),
69 &mut buf,69 &raw mut buf,
70 &mut buf_len,70 &raw mut buf_len,
71 )71 )
72 };72 };
73 let buf_slice: &[u8] = unsafe { std::slice::from_raw_parts(buf.cast(), buf_len) };73 let buf_slice: &[u8] = unsafe { std::slice::from_raw_parts(buf.cast(), buf_len) };
modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
9 evaluate_method, evaluate_named_param, Context, Pending, Thunk, Val,9 evaluate_method, evaluate_named_param, Context, Pending, Thunk, Val,
10};10};
11
12#[cfg(feature = "exp-preserve-order")]
13use crate::evaluate;
1114
12#[allow(clippy::too_many_lines)]15#[allow(clippy::too_many_lines)]
13#[allow(unused_variables)]16#[allow(unused_variables)]
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
143 false,143 false,
144 ) {144 ) {
145 let fctx = Pending::new();145 let fctx = Pending::new();
146 let mut new_bindings = FxHashMap::with_capacity(var.capacity_hint());146 let mut new_bindings = FxHashMap::with_capacity(var.binds_len());
147 let obj = obj.clone();147 let obj = obj.clone();
148 let value = Thunk::evaluated(Val::Arr(ArrValue::lazy(vec![148 let value = Thunk::evaluated(Val::Arr(ArrValue::lazy(vec![
149 Thunk::evaluated(Val::string(field.clone())),149 Thunk::evaluated(Val::string(field.clone())),
modifiedcrates/jrsonnet-evaluator/src/function/builtin.rsdiffbeforeafterboth
9898
99 fn call(&self, _loc: CallLocation<'_>, args: &[Option<Thunk<Val>>]) -> Result<Val> {99 fn call(&self, _loc: CallLocation<'_>, args: &[Option<Thunk<Val>>]) -> Result<Val> {
100 let args = args100 let args = args
101 .into_iter()101 .iter()
102 .map(|a| a.as_ref().expect("legacy natives have no default params"))102 .map(|a| a.as_ref().expect("legacy natives have no default params"))
103 .map(|a| a.evaluate())103 .map(Thunk::evaluate)
104 .collect::<Result<Vec<Val>>>()?;104 .collect::<Result<Vec<Val>>>()?;
105 self.handler.call(&args)105 self.handler.call(&args)
106 }106 }
modifiedcrates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth
1use std::{1use std::{
2 any::Any,2 any::Any, cell::{Cell, RefCell}, clone::Clone, cmp::Reverse, collections::hash_map::Entry, fmt::{self, Debug}, hash::{Hash, Hasher}, num::Saturating, ops::ControlFlow
3 cell::{Cell, RefCell},
4 clone::Clone,
5 collections::hash_map::Entry,
6 fmt::{self, Debug},
7 hash::{Hash, Hasher},
8 num::Saturating,
9 ops::ControlFlow,
10};3};
114
12use educe::Educe;5use educe::Educe;
3932
40 use jrsonnet_gcmodule::Trace;33 use jrsonnet_gcmodule::Trace;
4134
42 #[derive(Clone, Copy, Default, Debug, Trace)]35 #[derive(Clone, Copy, Default, Debug, Trace, PartialEq, Eq, PartialOrd, Ord)]
43 pub struct FieldIndex(());36 pub struct FieldIndex(());
44 impl FieldIndex {37 impl FieldIndex {
45 pub fn absolute(_v: u32) -> Self {38 pub fn absolute(_v: u32) -> Self {
46 Self(())39 Self(())
47 }40 }
41 #[must_use]
48 pub const fn next(self) -> Self {42 pub const fn next(self) -> Self {
49 Self(())43 Self(())
50 }44 }
51 }45 }
5246
53 #[derive(Clone, Copy, Default, Debug, Trace)]47 #[derive(Clone, Copy, Default, Debug, Trace, PartialEq, Eq, PartialOrd, Ord)]
54 pub struct SuperDepth(());48 pub struct SuperDepth(());
55 impl SuperDepth {49 impl SuperDepth {
56 pub(super) fn deepen(self) {}50 pub(super) fn deepen(self) {}
5953
60#[cfg(feature = "exp-preserve-order")]54#[cfg(feature = "exp-preserve-order")]
61pub mod ordering {55pub mod ordering {
62 use std::cmp::Reverse;
63
64 use jrsonnet_gcmodule::Trace;56 use jrsonnet_gcmodule::Trace;
6557
69 pub fn absolute(v: u32) -> Self {61 pub fn absolute(v: u32) -> Self {
70 Self(v)62 Self(v)
71 }63 }
64 #[must_use]
72 pub fn next(self) -> Self {65 pub fn next(self) -> Self {
73 Self(self.0 + 1)66 Self(self.0 + 1)
74 }67 }
78 pub struct SuperDepth(u32);71 pub struct SuperDepth(u32);
79 impl SuperDepth {72 impl SuperDepth {
80 pub(super) fn deepen(&mut self) {73 pub(super) fn deepen(&mut self) {
81 self.0 += 174 self.0 += 1;
82 }75 }
83 }76 }
84
85 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
86 pub struct FieldSortKey(Reverse<SuperDepth>, FieldIndex);
87 impl FieldSortKey {
88 pub fn new(depth: SuperDepth, index: FieldIndex) -> Self {
89 Self(Reverse(depth), index)
90 }
91 }
92}77}
78
79use ordering::{FieldIndex, SuperDepth};
9380
94#[cfg(feature = "exp-preserve-order")]81#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
95use ordering::FieldSortKey;82pub struct FieldSortKey(Reverse<SuperDepth>, FieldIndex);
96use ordering::{FieldIndex, SuperDepth};83impl FieldSortKey {
84 pub fn new(depth: SuperDepth, index: FieldIndex) -> Self {
85 Self(Reverse(depth), index)
86 }
87}
9788
98// 0 - add89// 0 - add
795struct FieldVisibilityData {786struct FieldVisibilityData {
796 omitted_until: Saturating<usize>,787 omitted_until: Saturating<usize>,
797 exists_visible: Option<Visibility>,788 exists_visible: Option<Visibility>,
798 #[cfg(feature = "exp-preserve-order")]789 #[allow(dead_code, reason = "used for exp-object-ordering, ZST otherwise")]
799 key: FieldSortKey,790 key: FieldSortKey,
800}791}
801impl FieldVisibilityData {792impl FieldVisibilityData {
804 .expect("non-existing fields shall be dropped at the end of fn fields_visibility()")795 .expect("non-existing fields shall be dropped at the end of fn fields_visibility()")
805 .is_visible()796 .is_visible()
806 }797 }
807 #[cfg(feature = "exp-preserve-order")]798 #[allow(dead_code, reason = "used for exp-object-ordering, ZST otherwise")]
808 fn sort_key(&self) -> FieldSortKey {799 fn sort_key(&self) -> FieldSortKey {
809 self.key800 self.key
810 }801 }
818 let mut omit_index = Saturating(0);809 let mut omit_index = Saturating(0);
819 for core in self.0.cores.iter().rev() {810 for core in self.0.cores.iter().rev() {
820 core.0811 core.0
821 .enum_fields_core(&mut super_depth, &mut |_depth, _index, name, visibility| {812 .enum_fields_core(&mut super_depth, &mut |depth, index, name, visibility| {
822 let entry = out.entry(name);813 let entry = out.entry(name);
823 let data = entry.or_insert(FieldVisibilityData {814 let data = entry.or_insert_with(|| FieldVisibilityData {
824 exists_visible: None,815 exists_visible: None,
825 #[cfg(feature = "exp-preserve-order")]
826 key: FieldSortKey::new(_depth, _index),816 key: FieldSortKey::new(depth, index),
827 omitted_until: omit_index,817 omitted_until: omit_index,
828 });818 });
829 match visibility {819 match visibility {
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
61 }61 }
62}62}
6363
64#[diagnostic::on_unimplemented(
65 note = "don't implement `ParseTypedObj` directly, it is automatically provided by `FromUntyped` derive"
66)]
64pub trait ParseTypedObj: Typed {67pub trait ParseTypedObj: Typed {
65 fn parse(obj: &ObjValue) -> Result<Self>;68 fn parse(obj: &ObjValue) -> Result<Self>;
66}69}
70
71#[diagnostic::on_unimplemented(
72 note = "don't implement `SerializeTypedObj` directly, it is automatically provided by `IntoUntyped` derive"
73)]
67pub trait SerializeTypedObj: Typed {74pub trait SerializeTypedObj: Typed {
68 fn serialize(self, out: &mut ObjValueBuilder) -> Result<()>;75 fn serialize(self, out: &mut ObjValueBuilder) -> Result<()>;
69 fn into_object(self) -> Result<ObjValue> {76 fn into_object(self) -> Result<ObjValue> {
modifiedcrates/jrsonnet-formatter/src/comments.rsdiffbeforeafterboth
136 }136 }
137 line = new_line.to_string();137 line = new_line.to_string();
138 }138 }
139 p!(out, string(line.to_string()) nl);139 p!(out, string(line.clone()) nl);
140 }140 }
141 }141 }
142 if doc {142 if doc {
modifiedcrates/jrsonnet-formatter/src/lib.rsdiffbeforeafterboth
38 items.into_rc_path()38 items.into_rc_path()
39 };39 };
40 let items =40 let items = new_line_group(pi!(@i; items(o) items(end_comments_items.into()))).into_rc_path();
41 new_line_group(pi!(@i; items(o.into()) items(end_comments_items.into()))).into_rc_path();
4241
43 let indented = with_indent(pi!(@i; nl items(items.into())));42 let indented = with_indent(pi!(@i; nl items(items.into())));
4443
355}354}
356impl Printable for ArgsDesc {355impl Printable for ArgsDesc {
357 fn print(&self, out: &mut PrintItems) {356 fn print(&self, out: &mut PrintItems) {
358 let start = LineNumber::new("args start line");
359 let end = LineNumber::new("args end line");
360 let multi_line = Rc::new(move |condition_context: &mut ConditionResolverContext| {
361 is_multiple_lines(condition_context, start, end)
362 });
363
364 let (children, end_comments) = children_between::<Arg>(
365 self.syntax().clone(),
366 self.l_paren_token().map(Into::into).as_ref(),
367 self.r_paren_token().map(Into::into).as_ref(),
368 None,
369 );
370
371 fn gen_args(children: Vec<Child<Arg>>, multi_line: ConditionResolver) -> PrintItems {357 fn gen_args(children: Vec<Child<Arg>>, multi_line: ConditionResolver) -> PrintItems {
372 let mut _out = PrintItems::new();358 let mut out = PrintItems::new();
373 let out = &mut _out;
374359
375 let mut args = children.into_iter().peekable();360 let mut args = children.into_iter().peekable();
376 while let Some(ele) = args.next() {361 while let Some(ele) = args.next() {
377 if ele.should_start_with_newline {362 if ele.should_start_with_newline {
378 p!(out, nl);363 p!(out, nl);
379 }364 }
380 format_comments(&ele.before_trivia, CommentLocation::AboveItem, out);365 format_comments(&ele.before_trivia, CommentLocation::AboveItem, &mut out);
381 let arg = ele.value;366 let arg = ele.value;
382 if arg.name().is_some() || arg.assign_token().is_some() {367 if arg.name().is_some() || arg.assign_token().is_some() {
383 p!(out, {arg.name()} str(" = "));368 p!(&mut out, {arg.name()} str(" = "));
384 }369 }
385 p!(out, { arg.expr() });370 p!(&mut out, { arg.expr() });
386 let has_more = args.peek().is_some();371 let has_more = args.peek().is_some();
387 if has_more {372 if has_more {
388 p!(out, str(","));373 p!(out, str(","));
389 } else {374 } else {
390 p!(out, if("trailing comma", multi_line, str(",")));375 p!(out, if("trailing comma", multi_line, str(",")));
391 }376 }
392 format_comments(&ele.inline_trivia, CommentLocation::ItemInline, out);377 format_comments(&ele.inline_trivia, CommentLocation::ItemInline, &mut out);
393 if has_more {378 if has_more {
394 p!(out, if_else("arg separator", multi_line, nl)(sonl));379 p!(out, if_else("arg separator", multi_line, nl)(sonl));
395 }380 }
396 }381 }
397 _out382
383 out
398 }384 }
385
386 let start = LineNumber::new("args start line");
387 let end = LineNumber::new("args end line");
388 let multi_line = Rc::new(move |condition_context: &mut ConditionResolverContext| {
389 is_multiple_lines(condition_context, start, end)
390 });
391
392 let (children, end_comments) = children_between::<Arg>(
393 self.syntax().clone(),
394 self.l_paren_token().map(Into::into).as_ref(),
395 self.r_paren_token().map(Into::into).as_ref(),
396 None,
397 );
399398
400 let args_items = new_line_group(gen_args(children, multi_line.clone())).into_rc_path();399 let args_items = new_line_group(gen_args(children, multi_line.clone())).into_rc_path();
401 let args_indented = with_indent(pi!(@i; nl items(args_items.into())));400 let args_indented = with_indent(pi!(@i; nl items(args_items.into())));
447}446}
448447
449impl Printable for ObjBody {448impl Printable for ObjBody {
449 #[allow(clippy::too_many_lines)]
450 fn print(&self, out: &mut PrintItems) {450 fn print(&self, out: &mut PrintItems) {
451 match self {451 match self {
452 Self::ObjBodyComp(l) => {452 Self::ObjBodyComp(l) => {
507 p!(out, nl <i str("}"));507 p!(out, nl <i str("}"));
508 }508 }
509 Self::ObjBodyMemberList(l) => {509 Self::ObjBodyMemberList(l) => {
510 fn gen_members(
511 children: Vec<Child<Member>>,
512 multi_line: ConditionResolver,
513 ) -> PrintItems {
514 let mut out = PrintItems::new();
515 let mut members = children.into_iter().peekable();
516 while let Some(mem) = members.next() {
517 if mem.should_start_with_newline {
518 p!(out, nl);
519 }
520 format_comments(&mem.before_trivia, CommentLocation::AboveItem, &mut out);
521 p!(&mut out, { mem.value });
522 let has_more = members.peek().is_some();
523 if has_more {
524 p!(out, str(","));
525 } else {
526 p!(out, if("trailing comma", multi_line, str(",")));
527 }
528 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, &mut out);
529 p!(out, if_else("member separator", multi_line, nl)(sonl));
530 }
531 out
532 }
533
510 let (children, end_comments) = children_between::<Member>(534 let (children, end_comments) = children_between::<Member>(
511 l.syntax().clone(),535 l.syntax().clone(),
531 })555 })
532 };556 };
533
534 fn gen_members(
535 children: Vec<Child<Member>>,
536 multi_line: ConditionResolver,
537 ) -> PrintItems {
538 let mut _out = PrintItems::new();
539 let out = &mut _out;
540 let mut members = children.into_iter().peekable();
541 while let Some(mem) = members.next() {
542 if mem.should_start_with_newline {
543 p!(out, nl);
544 }
545 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);
546 p!(out, { mem.value });
547 let has_more = members.peek().is_some();
548 if has_more {
549 p!(out, str(","));
550 } else {
551 p!(out, if("trailing comma", multi_line, str(",")));
552 }
553 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);
554 p!(out, if_else("member separator", multi_line, nl)(sonl));
555 }
556 _out
557 }
558557
559 let members_items =558 let members_items =
560 new_line_group(gen_members(children, multi_line.clone())).into_rc_path();559 new_line_group(gen_members(children, multi_line.clone())).into_rc_path();
718717
719impl Printable for ExprArray {718impl Printable for ExprArray {
720 fn print(&self, out: &mut PrintItems) {719 fn print(&self, out: &mut PrintItems) {
720 fn gen_elements(children: Vec<Child<Expr>>, multi_line: ConditionResolver) -> PrintItems {
721 let mut out = PrintItems::new();
722 let mut els = children.into_iter().peekable();
723 while let Some(el) = els.next() {
724 if el.should_start_with_newline {
725 p!(out, nl);
726 }
727 format_comments(&el.before_trivia, CommentLocation::AboveItem, &mut out);
728 p!(&mut out, { el.value });
729 let has_more = els.peek().is_some();
730 if has_more {
731 p!(out, str(","));
732 } else {
733 p!(out, if("trailing comma", multi_line, str(",")));
734 }
735 format_comments(&el.inline_trivia, CommentLocation::ItemInline, &mut out);
736 p!(out, if_else("element separator", multi_line, nl)(sonl));
737 }
738 out
739 }
740
721 let (children, end_comments) = children_between::<Expr>(741 let (children, end_comments) = children_between::<Expr>(
722 self.syntax().clone(),742 self.syntax().clone(),
740 Rc::new(move |ctx: &mut ConditionResolverContext| is_multiple_lines(ctx, start, end))760 Rc::new(move |ctx: &mut ConditionResolverContext| is_multiple_lines(ctx, start, end))
741 };761 };
742
743 fn gen_elements(children: Vec<Child<Expr>>, multi_line: ConditionResolver) -> PrintItems {
744 let mut _out = PrintItems::new();
745 let out = &mut _out;
746 let mut els = children.into_iter().peekable();
747 while let Some(el) = els.next() {
748 if el.should_start_with_newline {
749 p!(out, nl);
750 }
751 format_comments(&el.before_trivia, CommentLocation::AboveItem, out);
752 p!(out, { el.value });
753 let has_more = els.peek().is_some();
754 if has_more {
755 p!(out, str(","));
756 } else {
757 p!(out, if("trailing comma", multi_line, str(",")));
758 }
759 format_comments(&el.inline_trivia, CommentLocation::ItemInline, out);
760 p!(out, if_else("element separator", multi_line, nl)(sonl))
761 }
762 _out
763 }
764762
765 let els_items = new_line_group(gen_elements(children, multi_line.clone())).into_rc_path();763 let els_items = new_line_group(gen_elements(children, multi_line.clone())).into_rc_path();
766764
800 Self::ExprString(s) => p!(out, { s.text() }),798 Self::ExprString(s) => p!(out, { s.text() }),
801 Self::ExprNumber(n) => p!(out, { n.number() }),799 Self::ExprNumber(n) => p!(out, { n.number() }),
802 Self::ExprArray(a) => {800 Self::ExprArray(a) => {
803 p!(out, { a })801 p!(out, { a });
804 }802 }
805 Self::ExprObject(obj) => {803 Self::ExprObject(obj) => {
806 p!(out, { obj.obj_body() });804 p!(out, { obj.obj_body() });
861 pub indent: u8,859 pub indent: u8,
862}860}
861
862#[allow(
863 clippy::result_large_err,
864 reason = "TODO: there should be an intermediate representation for such reports"
865)]
863pub fn format(input: &str, opts: &FormatOptions) -> Result<String, SnippetBuilder> {866pub fn format(input: &str, opts: &FormatOptions) -> Result<String, SnippetBuilder> {
864 let (parsed, errors) = jrsonnet_rowan_parser::parse(input);867 let (parsed, errors) = jrsonnet_rowan_parser::parse(input);
865 if !errors.is_empty() {868 if !errors.is_empty() {
modifiedcrates/jrsonnet-macros/src/typed.rsdiffbeforeafterboth
156 // optional flatten is handled in same way as serde156 // optional flatten is handled in same way as serde
157 if self.attr.flatten {157 if self.attr.flatten {
158 return quote! {158 return quote! {
159 #ident: <#ty as TypedObj>::parse(&obj).ok(),159 #ident: <#ty as ParseTypedObj>::parse(&obj).ok(),
160 };160 };
161 }161 }
162162
190 // optional flatten is handled in same way as serde190 // optional flatten is handled in same way as serde
191 if self.attr.flatten {191 if self.attr.flatten {
192 return quote! {192 return quote! {
193 #ident: <#ty as TypedObj>::parse(&obj)?,193 #ident: <#ty as ParseTypedObj>::parse(&obj)?,
194 };194 };
195 }195 }
196196
232 if self.is_option {232 if self.is_option {
233 quote! {233 quote! {
234 if let Some(value) = self.#ident {234 if let Some(value) = self.#ident {
235 <#ty as TypedObj>::serialize(value, out)?;235 <#ty as SerializeTypedObj>::serialize(value, out)?;
236 }236 }
237 }237 }
238 } else {238 } else {
239 quote! {239 quote! {
240 <#ty as TypedObj>::serialize(self.#ident, out)?;240 <#ty as SerializeTypedObj>::serialize(self.#ident, out)?;
241 }241 }
242 }242 }
243 },243 },
modifiedcrates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth
224 },224 },
225 #[cfg(feature = "exp-destruct")]225 #[cfg(feature = "exp-destruct")]
226 Object {226 Object {
227 #[allow(clippy::type_complexity)]
227 fields: Vec<(IStr, Option<Destruct>, Option<Spanned<Expr>>)>,228 fields: Vec<(IStr, Option<Destruct>, Option<Rc<Spanned<Expr>>>)>,
228 rest: Option<DestructRest>,229 rest: Option<DestructRest>,
229 },230 },
230}231}
261 let mut out = 0;262 let mut out = 0;
262 for (_, into, _) in fields {263 for (_, into, _) in fields {
263 match into {264 match into {
264 Some(v) => out += v.capacity_hint(),265 Some(v) => out += v.binds_len(),
265 // Field is destructured to default name266 // Field is destructured to default name
266 None => out += 1,267 None => out += 1,
267 }268 }
modifiedcrates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth
119 }119 }
120 pub rule destruct_object(s: &ParserSettings) -> expr::Destruct120 pub rule destruct_object(s: &ParserSettings) -> expr::Destruct
121 = "{" _121 = "{" _
122 fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:expr(s) {v})? {(name, into, default)})**comma()122 fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:expr(s) {v})? {(name, into, default.map(Rc::new))})**comma()
123 rest:(123 rest:(
124 comma() rest:destruct_rest()? {rest}124 comma() rest:destruct_rest()? {rest}
125 / comma()? {None}125 / comma()? {None}
modifiedcrates/jrsonnet-rowan-parser/src/ast.rsdiffbeforeafterboth
22
3use crate::{SyntaxKind, SyntaxNode, SyntaxNodeChildren, SyntaxToken};3use crate::{SyntaxKind, SyntaxNode, SyntaxNodeChildren, SyntaxToken};
44
5/// The main trait to go from untyped `SyntaxNode` to a typed ast. The5/// The main trait to go from untyped `SyntaxNode` to a typed ast.
6///
6/// conversion itself has zero runtime cost: ast and syntax nodes have exactly7/// The conversion itself has zero runtime cost: ast and syntax nodes have exactly
7/// the same representation: a pointer to the tree root and a pointer to the8/// the same representation: a pointer to the tree root and a pointer to the
8/// node itself.9/// node itself.
9pub trait AstNode {10pub trait AstNode {
modifiedcrates/jrsonnet-rowan-parser/src/event.rsdiffbeforeafterboth
56 fn text_offset(&self) -> TextSize {56 fn text_offset(&self) -> TextSize {
57 if self.offset == 0 {57 if self.offset == 0 {
58 return 0.into();58 return 0.into();
59 };59 }
60 self.lexemes.get(self.offset).map_or_else(60 self.lexemes.get(self.offset).map_or_else(
61 || {61 || {
62 self.lexemes62 self.lexemes
modifiedcrates/jrsonnet-rowan-parser/src/lib.rsdiffbeforeafterboth
2626
27use self::{27use self::{
28 ast::support,28 ast::support,
29 generated::nodes::{Expr, ExprBinary, ExprObjExtend},29 generated::nodes::{Expr, ExprObjExtend},
30};30};
3131
32pub fn parse(input: &str) -> (SourceFile, Vec<LocatedSyntaxError>) {32pub fn parse(input: &str) -> (SourceFile, Vec<LocatedSyntaxError>) {
modifiedcrates/jrsonnet-rowan-parser/src/marker.rsdiffbeforeafterboth
141 new_m141 new_m
142 }142 }
143 /// Create new node around existing marker143 /// Create new node around existing marker
144 /// If previous_pos is set - the wrapping node would not include everything that happened between wrapped node end and the current position of the parser144 /// If `previous_pos` is set - the wrapping node would not include everything that happened between wrapped node end and the current position of the parser
145 fn wrap_raw(145 fn wrap_raw(
146 self,146 self,
147 p: &mut Parser,147 p: &mut Parser,
modifiedcrates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth
52 write!(f, "unexpected {found:?}, expecting {expected}")52 write!(f, "unexpected {found:?}, expecting {expected}")
53 }53 }
54 SyntaxError::Missing { expected } => write!(f, "missing {expected}"),54 SyntaxError::Missing { expected } => write!(f, "missing {expected}"),
55 SyntaxError::Custom { error } => write!(f, "{error}"),55 SyntaxError::Custom { error } | SyntaxError::Hint { error } => write!(f, "{error}"),
56 SyntaxError::Hint { error } => write!(f, "{error}"),
57 }56 }
58 }57 }
59}58}
492 } else {491 } else {
493 m.complete(p, MEMBER_FIELD_NORMAL)492 m.complete(p, MEMBER_FIELD_NORMAL)
494 };493 };
495 };494 }
496 while p.at_ts(COMPSPEC) {495 while p.at_ts(COMPSPEC) {
497 compspecs.push(compspec(p));496 compspecs.push(compspec(p));
498 }497 }
747 if p.at(T![:]) {746 if p.at(T![:]) {
748 p.bump();747 p.bump();
749 destruct(p);748 destruct(p);
750 };749 }
751 if p.at(T![=]) {750 if p.at(T![=]) {
752 p.bump();751 p.bump();
753 expr(p);752 expr(p);
modifiedcrates/jrsonnet-rowan-parser/src/string_block.rsdiffbeforeafterboth
1111
12use crate::SyntaxKind;12use crate::SyntaxKind;
1313
14pub(crate) fn lex_str_block_test<'d>(lex: &mut Lexer<'d, SyntaxKind>) {14pub(crate) fn lex_str_block_test(lex: &mut Lexer<'_, SyntaxKind>) {
15 let _ = lex_str_block(lex);15 let _ = lex_str_block(lex);
16}16}
1717
48 }48 }
4949
50 fn eat_if(&mut self, f: impl Fn(char) -> bool) -> usize {50 fn eat_if(&mut self, f: impl Fn(char) -> bool) -> usize {
51 if self.peek().map(f).unwrap_or(false) {51 if self.peek().is_some_and(f) {
52 self.index += 1;52 self.index += 1;
53 return 1;53 return 1;
54 }54 }
141 }141 }
142}142}
143143
144pub fn collect_lexed_str_block<'s>(144pub fn collect_lexed_str_block(input: &str) -> Result<CollectStrBlock<'_>, StringBlockError> {
145 input: &'s str,
146) -> Result<CollectStrBlock<'s>, StringBlockError> {
147 let mut collect = CollectStrBlock {145 let mut collect = CollectStrBlock {
148 truncate: false,146 truncate: false,
149 lines: vec![],147 lines: vec![],
179 }177 }
180178
181 fn mark_line(&mut self, line: &'d str) {179 fn mark_line(&mut self, line: &'d str) {
182 self.lines.push(line)180 self.lines.push(line);
183 }181 }
184}182}
185183
modifiedcrates/jrsonnet-rowan-parser/src/tests.rsdiffbeforeafterboth
2#![cfg(test)]2#![cfg(test)]
33
4use hi_doc::{Formatting, SnippetBuilder, Text};4use hi_doc::{Formatting, SnippetBuilder, Text};
5use thiserror::Error;
65
7use crate::{parse, AstNode};6use crate::{parse, AstNode};
87
14 if !errors.is_empty() && !text.is_empty() {13 if !errors.is_empty() && !text.is_empty() {
15 writeln!(out, "===").unwrap();14 writeln!(out, "===").unwrap();
16 for err in &errors {15 for err in &errors {
17 writeln!(out, "{:?}", err).unwrap();16 writeln!(out, "{err:?}").unwrap();
18 }17 }
19 let mut code = text.to_string();18 let mut code = text.to_string();
2019
modifiedcrates/jrsonnet-stdlib/src/regex.rsdiffbeforeafterboth
4use jrsonnet_evaluator::{4use jrsonnet_evaluator::{
5 error::{ErrorKind::*, Result},5 error::{ErrorKind::*, Result},
6 rustc_hash::FxBuildHasher,6 rustc_hash::FxBuildHasher,
7 typed::Typed,7 typed::{IntoUntyped, Typed},
8 val::StrValue,8 val::StrValue,
9 IStr, ObjValue, ObjValueBuilder,9 IStr, ObjValue, ObjValueBuilder,
10};10};
41 }41 }
42}42}
4343
44#[derive(Typed)]44#[derive(Typed, IntoUntyped)]
45pub struct RegexMatch {45pub struct RegexMatch {
46 string: IStr,46 string: IStr,
47 captures: Vec<IStr>,47 captures: Vec<IStr>,
modifiedtests/tests/common.rsdiffbeforeafterboth
41}41}
4242
43#[builtin]43#[builtin]
44#[allow(dead_code)]
44fn assert_throw(lazy: Thunk<Val>, message: String) -> Result<bool> {45fn assert_throw(lazy: Thunk<Val>, message: String) -> Result<bool> {
45 match lazy.evaluate() {46 match lazy.evaluate() {
46 Ok(_) => {47 Ok(_) => {
55}56}
5657
57#[builtin]58#[builtin]
59#[allow(dead_code)]
58fn param_names(fun: FuncVal) -> Vec<String> {60fn param_names(fun: FuncVal) -> Vec<String> {
59 fun.params()61 fun.params()
60 .iter()62 .iter()
modifiedtests/tests/typed_obj.rsdiffbeforeafterboth
9};9};
10use jrsonnet_stdlib::ContextInitializer;10use jrsonnet_stdlib::ContextInitializer;
1111
12#[derive(Clone, Typed, PartialEq, Debug)]12#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
13struct A {13struct A {
14 a: u32,14 a: u32,
15 b: u16,15 b: u16,
39 Ok(())39 Ok(())
40}40}
4141
42#[derive(Clone, Typed, PartialEq, Debug)]42#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
43struct B {43struct B {
44 a: u32,44 a: u32,
45 #[typed(rename = "c")]45 #[typed(rename = "c")]
62 Ok(())62 Ok(())
63}63}
6464
65#[derive(Clone, Typed, PartialEq, Debug)]65#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
66struct ObjectKind {66struct ObjectKind {
67 #[typed(rename = "apiVersion")]67 #[typed(rename = "apiVersion")]
68 api_version: String,68 api_version: String,
69 #[typed(rename = "kind")]69 #[typed(rename = "kind")]
70 kind: String,70 kind: String,
71}71}
7272
73#[derive(Clone, Typed, PartialEq, Debug)]73#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
74struct Object {74struct Object {
75 #[typed(flatten)]75 #[typed(flatten)]
76 kind: ObjectKind,76 kind: ObjectKind,
104 Ok(())104 Ok(())
105}105}
106106
107#[derive(Clone, Typed, PartialEq, Debug)]107#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
108struct C {108struct C {
109 a: Option<u32>,109 a: Option<u32>,
110 b: u16,110 b: u16,
142 Ok(())142 Ok(())
143}143}
144144
145#[derive(Clone, Typed, PartialEq, Debug)]145#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
146struct D {146struct D {
147 #[typed(flatten(ok))]147 #[typed(flatten(ok))]
148 e: Option<E>,148 e: Option<E>,
149 b: u16,149 b: u16,
150}150}
151151
152#[derive(Clone, Typed, PartialEq, Debug)]152#[derive(Clone, Typed, FromUntyped, IntoUntyped, PartialEq, Debug)]
153struct E {153struct E {
154 v: u32,154 v: u32,
155}155}
modifiedxtask/src/sourcegen/mod.rsdiffbeforeafterboth
65 is_lexer_error: true,65 is_lexer_error: true,
66 });66 });
67 }67 }
68 };68 }
69 continue;69 continue;
70 };70 }
71 let name = to_upper_snake_case(token);71 let name = to_upper_snake_case(token);
72 eprintln!("implicit kw: {token}");72 eprintln!("implicit kw: {token}");
73 kinds.define_token(TokenKind::Keyword {73 kinds.define_token(TokenKind::Keyword {
447 let trait_name = format_ident!("{}", trait_name);447 let trait_name = format_ident!("{}", trait_name);
448 let kinds: Vec<_> = nodes448 let kinds: Vec<_> = nodes
449 .iter()449 .iter()
450 .map(|name| format_ident!("{}", to_upper_snake_case(&name.name.to_string())))450 .map(|name| format_ident!("{}", to_upper_snake_case(&name.name)))
451 .collect();451 .collect();
452452
453 (453 (
555 if "{}[]()$".contains(token) {555 if "{}[]()$".contains(token) {
556 let c = token.chars().next().unwrap();556 let c = token.chars().next().unwrap();
557 quote! { #c }557 quote! { #c }
558 } else if token.contains(|v| v == '$') {558 } else if token.contains('$') {
559 quote! { #token }559 quote! { #token }
560 } else if token.chars().all(|v| ('a'..='z').contains(&v)) {560 } else if token.chars().all(|v: char| v.is_ascii_lowercase()) {
561 let i = Ident::new(&token, Span::call_site());561 let i = Ident::new(token, Span::call_site());
562 quote! { #i }562 quote! { #i }
563 } else {563 } else {
564 let cs = token.chars().map(|c| Punct::new(c, Spacing::Joint));564 let cs = token.chars().map(|c| Punct::new(c, Spacing::Joint));