1use crate::algorithm::Printer;
2use crate::iter::IterDelimited;
3use crate::INDENT;
4use std::ptr;
5use syn::{
6 AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument,
7 ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
8};
9
10#[derive(#[automatically_derived]
impl ::core::marker::Copy for PathKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PathKind {
#[inline]
fn clone(&self) -> PathKind { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PathKind {
#[inline]
fn eq(&self, other: &PathKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
11pub enum PathKind {
12 Simple,
14 Type,
16 Expr,
18}
19
20impl Printer {
21 pub fn path(&mut self, path: &Path, kind: PathKind) {
22 if !!path.segments.is_empty() {
::core::panicking::panic("assertion failed: !path.segments.is_empty()")
};assert!(!path.segments.is_empty());
23 for segment in path.segments.iter().delimited() {
24 if !segment.is_first || path.leading_colon.is_some() {
25 self.word("::");
26 }
27 self.path_segment(&segment, kind);
28 }
29 }
30
31 pub fn path_segment(&mut self, segment: &PathSegment, kind: PathKind) {
32 self.ident(&segment.ident);
33 self.path_arguments(&segment.arguments, kind);
34 }
35
36 fn path_arguments(&mut self, arguments: &PathArguments, kind: PathKind) {
37 match arguments {
38 PathArguments::None => {}
39 PathArguments::AngleBracketed(arguments) => {
40 self.angle_bracketed_generic_arguments(arguments, kind);
41 }
42 PathArguments::Parenthesized(arguments) => {
43 self.parenthesized_generic_arguments(arguments);
44 }
45 }
46 }
47
48 fn generic_argument(&mut self, arg: &GenericArgument) {
49 match arg {
50 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
51 GenericArgument::Lifetime(lifetime) => self.lifetime(lifetime),
52 GenericArgument::Type(ty) => self.ty(ty),
53 GenericArgument::Const(expr) => self.const_argument(expr),
54 GenericArgument::AssocType(assoc) => self.assoc_type(assoc),
55 GenericArgument::AssocConst(assoc) => self.assoc_const(assoc),
56 GenericArgument::Constraint(constraint) => self.constraint(constraint),
57 _ => {
::core::panicking::panic_fmt(format_args!("not implemented: {0}",
format_args!("unknown GenericArgument")));
}unimplemented!("unknown GenericArgument"),
58 }
59 }
60
61 pub fn angle_bracketed_generic_arguments(
62 &mut self,
63 generic: &AngleBracketedGenericArguments,
64 path_kind: PathKind,
65 ) {
66 if generic.args.is_empty() || path_kind == PathKind::Simple {
67 return;
68 }
69
70 if path_kind == PathKind::Expr {
71 self.word("::");
72 }
73 self.word("<");
74 self.cbox(INDENT);
75 self.zerobreak();
76
77 #[derive(#[automatically_derived]
impl ::core::cmp::Ord for Group {
#[inline]
fn cmp(&self, other: &Group) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Group {
#[inline]
fn partial_cmp(&self, other: &Group)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Group {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for Group {
#[inline]
fn eq(&self, other: &Group) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
80 enum Group {
81 First,
82 Second,
83 }
84 fn group(arg: &GenericArgument) -> Group {
85 match arg {
86 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
87 GenericArgument::Lifetime(_) => Group::First,
88 GenericArgument::Type(_)
89 | GenericArgument::Const(_)
90 | GenericArgument::AssocType(_)
91 | GenericArgument::AssocConst(_)
92 | GenericArgument::Constraint(_) => Group::Second,
93 _ => Group::Second,
94 }
95 }
96 let last = generic.args.iter().max_by_key(|param| group(param));
97 for current_group in [Group::First, Group::Second] {
98 for arg in &generic.args {
99 if group(arg) == current_group {
100 self.generic_argument(arg);
101 self.trailing_comma(ptr::eq(arg, last.unwrap()));
102 }
103 }
104 }
105
106 self.offset(-INDENT);
107 self.end();
108 self.word(">");
109 }
110
111 fn assoc_type(&mut self, assoc: &AssocType) {
112 self.ident(&assoc.ident);
113 if let Some(generics) = &assoc.generics {
114 self.angle_bracketed_generic_arguments(generics, PathKind::Type);
115 }
116 self.word(" = ");
117 self.ty(&assoc.ty);
118 }
119
120 fn assoc_const(&mut self, assoc: &AssocConst) {
121 self.ident(&assoc.ident);
122 if let Some(generics) = &assoc.generics {
123 self.angle_bracketed_generic_arguments(generics, PathKind::Type);
124 }
125 self.word(" = ");
126 self.const_argument(&assoc.value);
127 }
128
129 fn constraint(&mut self, constraint: &Constraint) {
130 self.ident(&constraint.ident);
131 if let Some(generics) = &constraint.generics {
132 self.angle_bracketed_generic_arguments(generics, PathKind::Type);
133 }
134 self.ibox(INDENT);
135 for bound in constraint.bounds.iter().delimited() {
136 if bound.is_first {
137 self.word(": ");
138 } else {
139 self.space();
140 self.word("+ ");
141 }
142 self.type_param_bound(&bound);
143 }
144 self.end();
145 }
146
147 fn parenthesized_generic_arguments(&mut self, arguments: &ParenthesizedGenericArguments) {
148 self.cbox(INDENT);
149 self.word("(");
150 self.zerobreak();
151 for ty in arguments.inputs.iter().delimited() {
152 self.ty(&ty);
153 self.trailing_comma(ty.is_last);
154 }
155 self.offset(-INDENT);
156 self.word(")");
157 self.return_type(&arguments.output);
158 self.end();
159 }
160
161 pub fn qpath(&mut self, qself: &Option<QSelf>, path: &Path, kind: PathKind) {
162 let Some(qself) = qself else {
163 self.path(path, kind);
164 return;
165 };
166
167 if !(qself.position < path.segments.len()) {
::core::panicking::panic("assertion failed: qself.position < path.segments.len()")
};assert!(qself.position < path.segments.len());
168
169 self.word("<");
170 self.ty(&qself.ty);
171
172 let mut segments = path.segments.iter();
173 if qself.position > 0 {
174 self.word(" as ");
175 for segment in segments.by_ref().take(qself.position).delimited() {
176 if !segment.is_first || path.leading_colon.is_some() {
177 self.word("::");
178 }
179 self.path_segment(&segment, PathKind::Type);
180 if segment.is_last {
181 self.word(">");
182 }
183 }
184 } else {
185 self.word(">");
186 }
187 for segment in segments {
188 self.word("::");
189 self.path_segment(segment, kind);
190 }
191 }
192}