1use std::fmt::Debug;
23
24use quote::ToTokens;
25use serde::ser::SerializeMap;
26use serde::{Serialize, Serializer};
27use syn::punctuated::Punctuated;
28use syn::{
29 Abi,
30 AngleBracketedGenericArguments,
31 BoundLifetimes,
32 Expr,
33 ExprLit,
34 GenericArgument,
35 GenericParam,
36 Generics,
37 LifetimeParam,
38 ParenthesizedGenericArguments,
39 Pat,
40 PatType,
41 Path,
42 PathArguments,
43 PathSegment,
44 ReturnType,
45 Token,
46 TraitBoundModifier,
47 Type,
48 TypeBareFn,
49 TypeParam,
50 TypeParamBound,
51 TypePath,
52 WhereClause,
53 WherePredicate,
54};
55
56#[derive(Clone, Debug, Eq, PartialEq)]
58pub(crate) enum Node {
59 Name(String),
61 Link { value: String, target: String },
63 Keyword(&'static str),
65 Punctuation(&'static str),
67 Space,
69 Newline,
71 Indent,
73 Operator(&'static str),
75 Returns,
77 Literal(String),
79 Lifetime(String),
82}
83
84impl Serialize for Node {
85 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86 where
87 S: Serializer,
88 {
89 match self {
90 Node::Name(n) => {
91 let mut map = serializer.serialize_map(Some(2))?;
92 map.serialize_entry("type", "name")?;
93 map.serialize_entry("value", n)?;
94 map.end()
95 }
96 Node::Link {
97 value,
98 target,
99 } => {
100 let mut map = serializer.serialize_map(Some(3))?;
101 map.serialize_entry("type", "link")?;
102 map.serialize_entry("value", value)?;
103 map.serialize_entry("target", target)?;
104 map.end()
105 }
106 Node::Keyword(k) => {
107 let mut map = serializer.serialize_map(Some(2))?;
108 map.serialize_entry("type", "keyword")?;
109 map.serialize_entry("value", k)?;
110 map.end()
111 }
112 Node::Punctuation(p) => {
113 let mut map = serializer.serialize_map(Some(2))?;
114 map.serialize_entry("type", "punctuation")?;
115 map.serialize_entry("value", p)?;
116 map.end()
117 }
118 Node::Space => {
119 let mut map = serializer.serialize_map(Some(1))?;
120 map.serialize_entry("type", "space")?;
121 map.end()
122 }
123 Node::Newline => {
124 let mut map = serializer.serialize_map(Some(1))?;
125 map.serialize_entry("type", "newline")?;
126 map.end()
127 }
128 Node::Indent => {
129 let mut map = serializer.serialize_map(Some(1))?;
130 map.serialize_entry("type", "indent")?;
131 map.end()
132 }
133 Node::Operator(o) => {
134 let mut map = serializer.serialize_map(Some(2))?;
135 map.serialize_entry("type", "operator")?;
136 map.serialize_entry("value", o)?;
137 map.end()
138 }
139 Node::Returns => {
140 let mut map = serializer.serialize_map(Some(1))?;
141 map.serialize_entry("type", "returns")?;
142 map.end()
143 }
144 Node::Literal(l) => {
145 let mut map = serializer.serialize_map(Some(2))?;
146 map.serialize_entry("type", "literal")?;
147 map.serialize_entry("value", l)?;
148 map.end()
149 }
150 Node::Lifetime(lt) => {
151 let mut map = serializer.serialize_map(Some(2))?;
152 map.serialize_entry("type", "lifetime")?;
153 map.serialize_entry("value", lt)?;
154 map.end()
155 }
156 }
157 }
158}
159
160fn type_param_bound_name(type_param_bound: &TypeParamBound) -> String {
164 match type_param_bound {
165 TypeParamBound::Trait(t) => t.path.segments.last().map(|s| s.ident.to_string()).unwrap(),
166 TypeParamBound::Lifetime(l) => l.to_string(),
167 TypeParamBound::Verbatim(_) => panic!("Cannot determine name for verbatim type"),
168 x => {
169 panic!("Unsupported bound type {:?}", x)
170 }
171 }
172}
173
174fn type_path_name(type_path: &TypePath) -> String {
179 type_path
180 .path
181 .segments
182 .iter()
183 .map(|s| s.ident.to_string())
184 .collect::<Vec<String>>()
185 .join("::")
186}
187
188pub(crate) fn type_name(ty: &Type) -> String {
192 match ty {
193 Type::Array(a) => format!("[{}; ?]", type_name(&a.elem)),
194 Type::BareFn(f) => format!(
195 "fn ({}){}",
196 f.inputs
197 .iter()
198 .map(|i| type_name(&i.ty))
199 .collect::<Vec<String>>()
200 .join(", "),
201 match &f.output {
202 ReturnType::Type(_, r_ty) => {
203 format!(" -> {}", type_name(r_ty))
204 }
205 _ => String::new(),
206 }
207 ),
208 Type::Group(g) => type_name(&g.elem),
209 Type::ImplTrait(t) => format!(
210 "impl {}",
211 t.bounds
212 .iter()
213 .map(type_param_bound_name)
214 .collect::<Vec<String>>()
215 .join(" + ")
216 ),
217 Type::Infer(_) | Type::Macro(_) => "_".into(),
218 Type::Never(_) => "!".into(),
219 Type::Paren(p) => format!("({})", type_name(&p.elem)),
220 Type::Path(p) => type_path_name(p),
221 Type::Ptr(p) => format!("*{}", type_name(&p.elem)),
222 Type::Reference(r) => format!("&{}", type_name(&r.elem)),
223 Type::Slice(s) => format!("[{}]", type_name(&s.elem)),
224 Type::TraitObject(t) => format!(
225 "dyn {}",
226 t.bounds
227 .iter()
228 .map(type_param_bound_name)
229 .collect::<Vec<String>>()
230 .join(" + ")
231 ),
232 Type::Tuple(t) => format!(
233 "({})",
234 t.elems
235 .iter()
236 .map(type_name)
237 .collect::<Vec<String>>()
238 .join(", ")
239 ),
240 Type::Verbatim(_) => panic!("Cannot determine name for verbatim type"),
241 x => panic!("Unsupported type category {:?}", x),
242 }
243}
244
245fn nodes_for_expr_lit(expr_lit: &ExprLit) -> Vec<Node> {
247 vec![Node::Literal(expr_lit.lit.to_token_stream().to_string())]
251}
252
253fn nodes_for_generic_argument(generic_arg: &GenericArgument) -> Vec<Node> {
255 let mut nodes = vec![];
256 match generic_arg {
257 GenericArgument::Lifetime(lt) => nodes.push(Node::Lifetime(lt.to_string())),
258 GenericArgument::Type(t) => nodes.extend(nodes_for_type(t)),
259 GenericArgument::Const(_) => {
260 nodes.push(Node::Keyword("<const arg>"));
263 }
264 GenericArgument::AssocType(at) => {
265 nodes.push(Node::Name(at.ident.to_string()));
266 if let Some(ab) = &at.generics {
267 nodes.extend(nodes_for_angle_bracket_generic_args(ab));
268 }
269 nodes.push(Node::Punctuation(" = "));
270 nodes.extend(nodes_for_type(&at.ty));
271 }
272 GenericArgument::AssocConst(ac) => {
273 nodes.push(Node::Name(ac.ident.to_string()));
274 if let Some(ab) = &ac.generics {
275 nodes.extend(nodes_for_angle_bracket_generic_args(ab));
276 }
277 nodes.push(Node::Punctuation(" = "));
279 nodes.push(Node::Keyword("<default>"));
280 }
281 GenericArgument::Constraint(c) => {
282 nodes.push(Node::Name(c.ident.to_string()));
283 if let Some(ab) = &c.generics {
284 nodes.extend(nodes_for_angle_bracket_generic_args(ab));
285 }
286 nodes.push(Node::Punctuation(": "));
287 nodes.extend(nodes_for_type_param_bounds(&c.bounds));
288 }
289 x => panic!("Unknown generic argument type {:?}", x),
290 }
291 nodes
292}
293
294fn nodes_for_angle_bracket_generic_args(angled_args: &AngleBracketedGenericArguments) -> Vec<Node> {
296 let mut nodes = vec![];
297 if angled_args.colon2_token.is_some() {
298 nodes.push(Node::Punctuation("::"));
299 }
300 nodes.push(Node::Punctuation("<"));
301 for arg in &angled_args.args {
302 nodes.extend(nodes_for_generic_argument(arg));
303 nodes.push(Node::Punctuation(", "));
304 }
305
306 nodes.pop();
307 nodes.push(Node::Punctuation(">"));
308 nodes
309}
310
311fn nodes_for_parenthesized_generic_args(paren_args: &ParenthesizedGenericArguments) -> Vec<Node> {
313 let mut nodes = vec![Node::Punctuation("(")];
314 for ty in &paren_args.inputs {
315 nodes.extend(nodes_for_type(ty));
316 nodes.push(Node::Punctuation(", "));
317 }
318 nodes.pop();
319 nodes.push(Node::Punctuation(")"));
320 nodes.extend(nodes_for_return_type(&paren_args.output));
321 nodes
322}
323
324fn nodes_for_path_segment(segment: &PathSegment, make_link: bool) -> Vec<Node> {
326 let mut nodes = if make_link {
327 vec![Node::Link {
328 value: segment.ident.to_string(),
329 target: segment.ident.to_string(),
330 }]
331 }
332 else {
333 vec![Node::Name(segment.ident.to_string())]
334 };
335 match &segment.arguments {
336 PathArguments::None => {}
337 PathArguments::AngleBracketed(ab) => {
338 nodes.extend(nodes_for_angle_bracket_generic_args(ab));
339 }
340 PathArguments::Parenthesized(p) => {
341 nodes.extend(nodes_for_parenthesized_generic_args(p));
342 }
343 }
344 nodes
345}
346
347pub(crate) fn nodes_for_path(path: &Path) -> Vec<Node> {
349 let mut nodes = vec![];
350 if path.leading_colon.is_some() {
351 nodes.push(Node::Punctuation("::"));
352 }
353 for (idx, segment) in path.segments.iter().enumerate() {
354 nodes.extend(nodes_for_path_segment(segment, idx == 0));
355 nodes.push(Node::Punctuation("::"));
356 }
357 nodes.pop();
358 nodes
359}
360
361pub(crate) fn nodes_for_abi_opt(abi: &Option<Abi>) -> Vec<Node> {
363 abi.as_ref()
364 .map(|abi| {
365 let mut nodes = vec![Node::Keyword("extern"), Node::Space];
366 if let Some(s) = &abi.name {
367 nodes.extend_from_slice(&[Node::Literal(s.value()), Node::Space]);
368 }
369 nodes
370 })
371 .unwrap_or_default()
372}
373
374pub(crate) fn nodes_for_type(ty: &Type) -> Vec<Node> {
376 let mut nodes = vec![];
377 match ty {
378 Type::Array(a) => {
379 nodes.push(Node::Punctuation("["));
380 nodes.extend(nodes_for_type(&a.elem));
381 nodes.push(Node::Punctuation("; "));
382
383 if let Expr::Lit(l) = &a.len {
387 nodes.extend(nodes_for_expr_lit(l));
388 }
389 else {
390 nodes.push(Node::Punctuation("?"))
391 }
392
393 nodes.push(Node::Punctuation("]"));
394 }
395 Type::BareFn(bf) => {
396 nodes.extend(nodes_for_bare_fn(bf));
397 }
398 Type::Group(_) => {} Type::ImplTrait(i) => {
400 nodes.push(Node::Keyword("impl"));
401 nodes.push(Node::Space);
402 nodes.extend(nodes_for_type_param_bounds(&i.bounds));
403 }
404 Type::Infer(_) => {
405 nodes.push(Node::Punctuation("_"));
406 }
407 Type::Macro(_) => {
408 nodes.push(Node::Punctuation("?"));
409 }
410 Type::Never(_) => {
411 nodes.push(Node::Punctuation("!"));
412 }
413 Type::Paren(p) => {
414 nodes.push(Node::Punctuation("("));
415 nodes.extend(nodes_for_type(&p.elem));
416 nodes.push(Node::Punctuation(")"));
417 }
418 Type::Path(p) => {
419 nodes.extend(nodes_for_path(&p.path));
422 }
423 Type::Ptr(p) => {
424 nodes.push(Node::Operator("*"));
425 if p.const_token.is_some() {
426 nodes.push(Node::Keyword("const"));
427 nodes.push(Node::Space);
428 }
429 if p.mutability.is_some() {
430 nodes.push(Node::Keyword("mut"));
431 nodes.push(Node::Space);
432 }
433 nodes.extend(nodes_for_type(&p.elem));
434 }
435 Type::Reference(r) => {
436 nodes.push(Node::Punctuation("&"));
437 if let Some(lt) = &r.lifetime {
438 nodes.push(Node::Lifetime(lt.to_string()));
439 nodes.push(Node::Space);
440 }
441 if r.mutability.is_some() {
442 nodes.push(Node::Keyword("mut"));
443 nodes.push(Node::Space);
444 }
445 nodes.extend(nodes_for_type(&r.elem));
446 }
447 Type::Slice(s) => {
448 nodes.push(Node::Punctuation("["));
449 nodes.extend(nodes_for_type(&s.elem));
450 nodes.push(Node::Punctuation("]"));
451 }
452 Type::TraitObject(t) => {
453 nodes.push(Node::Keyword("dyn"));
454 nodes.push(Node::Space);
455 nodes.extend(nodes_for_type_param_bounds(&t.bounds));
456 }
457 Type::Tuple(t) => {
458 nodes.push(Node::Punctuation("("));
459 for elem in &t.elems {
460 nodes.extend(nodes_for_type(elem));
461 nodes.push(Node::Punctuation(", "));
462 }
463 if !t.elems.is_empty() {
464 nodes.pop();
465 }
466 nodes.push(Node::Punctuation(")"));
467 }
468 Type::Verbatim(_) => {}
469 x => panic!("Unsupported type category {:?}", x),
470 }
471
472 nodes
473}
474
475fn nodes_for_lifetime_param(lifetime_param: &LifetimeParam) -> Vec<Node> {
477 let mut nodes = vec![Node::Lifetime(lifetime_param.lifetime.to_string())];
478 if lifetime_param.colon_token.is_some() {
479 nodes.push(Node::Punctuation(": "));
480 for bound in &lifetime_param.bounds {
481 nodes.push(Node::Lifetime(bound.to_string()));
482 nodes.push(Node::Punctuation(" + "));
483 }
484 nodes.pop();
485 }
486
487 nodes
488}
489
490fn nodes_for_bound_lifetimes(bound_lts: &BoundLifetimes) -> Vec<Node> {
492 let mut nodes = vec![];
493 nodes.extend_from_slice(&[Node::Keyword("for"), Node::Punctuation("<")]);
494 for lt in &bound_lts.lifetimes {
495 nodes.extend(nodes_for_generic_param(lt));
496 nodes.push(Node::Punctuation(", "));
497 }
498 nodes.pop();
499 nodes.extend_from_slice(&[Node::Punctuation(">"), Node::Space]);
500 nodes
501}
502
503fn nodes_for_type_param_bound(type_param_bound: &TypeParamBound) -> Vec<Node> {
505 let mut nodes = vec![];
506 match type_param_bound {
507 TypeParamBound::Trait(t) => {
508 if t.paren_token.is_some() {
509 nodes.push(Node::Punctuation("("));
510 }
511 if matches!(t.modifier, TraitBoundModifier::Maybe(_)) {
512 nodes.push(Node::Punctuation("?"));
513 }
514 if let Some(blt) = &t.lifetimes {
515 nodes.extend(nodes_for_bound_lifetimes(blt));
516 }
517 nodes.extend(nodes_for_path(&t.path));
518 if t.paren_token.is_some() {
519 nodes.push(Node::Punctuation(")"));
520 }
521 }
522 TypeParamBound::Lifetime(lt) => {
523 nodes.push(Node::Lifetime(lt.to_string()));
524 }
525 TypeParamBound::Verbatim(_) => {}
526 x => {
527 panic!("Unsupported bound type {:?}", x)
528 }
529 }
530
531 nodes
532}
533
534fn nodes_for_type_param_bounds(
536 type_param_bounds: &Punctuated<TypeParamBound, Token![+]>,
537) -> Vec<Node> {
538 let mut nodes = vec![];
539 for bound in type_param_bounds {
540 nodes.extend(nodes_for_type_param_bound(bound));
541 nodes.push(Node::Punctuation(" + "))
542 }
543 nodes.pop();
544 nodes
545}
546
547fn nodes_for_type_param(type_param: &TypeParam) -> Vec<Node> {
549 let mut nodes = vec![Node::Name(type_param.ident.to_string())];
550 if type_param.colon_token.is_some() {
551 nodes.push(Node::Punctuation(": "));
552 nodes.extend(nodes_for_type_param_bounds(&type_param.bounds));
553 }
554
555 nodes
556}
557
558fn nodes_for_generic_param(generic_param: &GenericParam) -> Vec<Node> {
560 match generic_param {
561 GenericParam::Lifetime(lt) => nodes_for_lifetime_param(lt),
562 GenericParam::Type(ty) => nodes_for_type_param(ty),
563 GenericParam::Const(c) => {
564 let mut nodes = vec![
565 Node::Keyword("const"),
566 Node::Space,
567 Node::Name(c.ident.to_string()),
568 Node::Punctuation(": "),
569 ];
570 nodes.extend(nodes_for_type(&c.ty));
571
572 nodes
573 }
574 }
575}
576
577pub(crate) fn nodes_for_generics(generics: &Generics) -> Vec<Node> {
582 if generics.params.is_empty() {
583 return vec![];
584 }
585
586 let mut nodes = vec![Node::Punctuation("<")];
587
588 for generic in &generics.params {
589 nodes.extend(nodes_for_generic_param(generic));
590 nodes.push(Node::Punctuation(", "));
591 }
592
593 nodes.pop();
595 nodes.push(Node::Punctuation(">"));
596
597 nodes
598}
599
600pub(crate) fn nodes_for_where_clause(where_clause: &WhereClause) -> Vec<Node> {
605 let mut nodes = vec![Node::Newline, Node::Keyword("where")];
606 for predicate in &where_clause.predicates {
607 nodes.extend_from_slice(&[Node::Newline, Node::Indent]);
608 match predicate {
609 WherePredicate::Lifetime(lt) => {
610 nodes.extend_from_slice(&[
611 Node::Lifetime(lt.lifetime.to_string()),
612 Node::Punctuation(": "),
613 ]);
614 for bound in <.bounds {
615 nodes.extend_from_slice(&[
616 Node::Lifetime(bound.to_string()),
617 Node::Punctuation(" + "),
618 ]);
619 }
620 nodes.pop();
621 }
622 WherePredicate::Type(ty) => {
623 if let Some(blt) = &ty.lifetimes {
624 nodes.extend(nodes_for_bound_lifetimes(blt));
625 }
626 nodes.extend(nodes_for_type(&ty.bounded_ty));
627 nodes.push(Node::Punctuation(": "));
628 nodes.extend(nodes_for_type_param_bounds(&ty.bounds));
629 }
630 x => {
631 panic!("Unknown where predicate type {:?}", x)
632 }
633 }
634 nodes.push(Node::Punctuation(","))
635 }
636 nodes.pop();
637
638 nodes
639}
640
641pub(crate) fn nodes_for_pat_type(pat_type: &PatType) -> Vec<Node> {
643 let mut nodes = vec![];
644 nodes.extend(nodes_for_pat(&pat_type.pat));
645 nodes.push(Node::Punctuation(": "));
646 nodes.extend(nodes_for_type(&pat_type.ty));
647 nodes
648}
649
650fn nodes_for_pat(pat: &Pat) -> Vec<Node> {
652 let mut nodes = vec![];
653 match pat {
654 Pat::Const(_) => {
655 nodes.push(Node::Keyword("<const block>"));
656 }
657 Pat::Ident(i) => {
658 if i.by_ref.is_some() {
659 nodes.push(Node::Keyword("ref"));
660 nodes.push(Node::Space);
661 }
662 if i.mutability.is_some() {
663 nodes.push(Node::Keyword("mut"));
664 nodes.push(Node::Space);
665 }
666 nodes.push(Node::Name(i.ident.to_string()));
667 }
668 Pat::Lit(l) => nodes.extend(nodes_for_expr_lit(l)),
669 Pat::Macro(_) => nodes.push(Node::Literal("macro".into())),
670 Pat::Or(o) => {
671 if o.leading_vert.is_some() {
672 nodes.push(Node::Operator("| "));
673 }
674 for case in &o.cases {
675 nodes.extend(nodes_for_pat(case));
676 nodes.push(Node::Operator(" | "));
677 }
678 nodes.pop();
679 }
680 Pat::Paren(p) => {
681 nodes.push(Node::Punctuation("("));
682 nodes.extend(nodes_for_pat(&p.pat));
683 nodes.push(Node::Punctuation(")"));
684 }
685 Pat::Path(p) => {
686 nodes.extend(nodes_for_path(&p.path))
688 }
689 Pat::Range(_) => {
690 nodes.push(Node::Literal("range".into()));
691 }
692 Pat::Reference(r) => {
693 nodes.push(Node::Punctuation("&"));
694 if r.mutability.is_some() {
695 nodes.push(Node::Keyword("mut"));
696 }
697 nodes.push(Node::Space);
698 nodes.extend(nodes_for_pat(&r.pat))
699 }
700 Pat::Rest(_) => {
701 nodes.push(Node::Operator(".."));
702 }
703 Pat::Slice(s) => {
704 nodes.push(Node::Punctuation("["));
705 for pat in &s.elems {
706 nodes.extend(nodes_for_pat(pat));
707 nodes.push(Node::Punctuation(", "));
708 }
709 nodes.pop();
710 nodes.push(Node::Punctuation("]"));
711 }
712 Pat::Struct(s) => {
713 nodes.extend(nodes_for_path(&s.path));
716 nodes.push(Node::Space);
717 nodes.push(Node::Punctuation("{..}"));
718 }
719 Pat::Tuple(t) => {
720 nodes.push(Node::Punctuation("("));
721 for pat in &t.elems {
722 nodes.extend(nodes_for_pat(pat));
723 nodes.push(Node::Punctuation(", "));
724 }
725 nodes.pop();
726 nodes.push(Node::Punctuation(")"));
727 }
728 Pat::TupleStruct(ts) => {
729 nodes.extend(nodes_for_path(&ts.path));
731 nodes.push(Node::Punctuation("("));
732 for pat in &ts.elems {
733 nodes.extend(nodes_for_pat(pat));
734 nodes.push(Node::Punctuation(", "));
735 }
736 nodes.pop();
737 nodes.push(Node::Punctuation(")"));
738 }
739 Pat::Type(t) => {
740 nodes.extend(nodes_for_pat_type(t));
741 }
742 Pat::Verbatim(_) => {}
743 Pat::Wild(_) => {
744 nodes.push(Node::Punctuation("_"));
745 }
746 x => panic!("Unsupported pattern type {:?} in fn inputs", x),
747 }
748 nodes
749}
750
751pub(crate) fn nodes_for_return_type(return_type: &ReturnType) -> Vec<Node> {
753 let mut nodes = vec![];
754 if let ReturnType::Type(_, ty) = return_type {
755 nodes.extend_from_slice(&[Node::Space, Node::Returns, Node::Space]);
756 nodes.extend(nodes_for_type(ty));
757 }
758
759 nodes
760}
761
762pub(crate) fn nodes_for_bare_fn(bare_fn: &TypeBareFn) -> Vec<Node> {
764 let mut nodes = Vec::new();
765 if bare_fn.unsafety.is_some() {
766 nodes.push(Node::Keyword("unsafe"));
767 nodes.push(Node::Space);
768 }
769 nodes.extend(nodes_for_abi_opt(&bare_fn.abi));
770 nodes.push(Node::Keyword("fn"));
771 nodes.push(Node::Space);
772
773 nodes.push(Node::Punctuation("("));
775 for arg in &bare_fn.inputs {
776 nodes.extend(nodes_for_type(&arg.ty));
777 nodes.push(Node::Punctuation(", "));
778 }
779
780 if bare_fn.variadic.is_some() {
782 nodes.push(Node::Punctuation("..."));
783 }
784 else if !bare_fn.inputs.is_empty() {
785 nodes.pop();
786 }
787 nodes.push(Node::Punctuation(")"));
789
790 nodes.extend(nodes_for_return_type(&bare_fn.output));
792
793 nodes
794}