1use proc_macro2::Span;
10use syn::{spanned::Spanned, *};
11
12pub(crate) fn namespace_ty(span: Span) -> Type {
14 Type::Path(TypePath {
15 qself: None,
16 path: Path {
17 leading_colon: Some(syn::token::PathSep {
18 spans: [span, span],
19 }),
20 segments: [
21 PathSegment {
22 ident: Ident::new("xso", span),
23 arguments: PathArguments::None,
24 },
25 PathSegment {
26 ident: Ident::new("exports", span),
27 arguments: PathArguments::None,
28 },
29 PathSegment {
30 ident: Ident::new("rxml", span),
31 arguments: PathArguments::None,
32 },
33 PathSegment {
34 ident: Ident::new("Namespace", span),
35 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
36 colon2_token: None,
37 lt_token: token::Lt { spans: [span] },
38 args: [GenericArgument::Lifetime(Lifetime {
39 apostrophe: Span::call_site(),
40 ident: Ident::new("static", Span::call_site()),
41 })]
42 .into_iter()
43 .collect(),
44 gt_token: token::Gt { spans: [span] },
45 }),
46 },
47 ]
48 .into_iter()
49 .collect(),
50 },
51 })
52}
53
54pub(crate) fn ncnamestr_ty(span: Span) -> Type {
56 Type::Path(TypePath {
57 qself: None,
58 path: Path {
59 leading_colon: Some(syn::token::PathSep {
60 spans: [span, span],
61 }),
62 segments: [
63 PathSegment {
64 ident: Ident::new("xso", span),
65 arguments: PathArguments::None,
66 },
67 PathSegment {
68 ident: Ident::new("exports", span),
69 arguments: PathArguments::None,
70 },
71 PathSegment {
72 ident: Ident::new("rxml", span),
73 arguments: PathArguments::None,
74 },
75 PathSegment {
76 ident: Ident::new("NcNameStr", span),
77 arguments: PathArguments::None,
78 },
79 ]
80 .into_iter()
81 .collect(),
82 },
83 })
84}
85
86pub(crate) fn cow_ty(ty: Type, lifetime: Lifetime) -> Type {
88 let span = ty.span();
89 Type::Path(TypePath {
90 qself: None,
91 path: Path {
92 leading_colon: Some(syn::token::PathSep {
93 spans: [span, span],
94 }),
95 segments: [
96 PathSegment {
97 ident: Ident::new("xso", span),
98 arguments: PathArguments::None,
99 },
100 PathSegment {
101 ident: Ident::new("exports", span),
102 arguments: PathArguments::None,
103 },
104 PathSegment {
105 ident: Ident::new("alloc", span),
106 arguments: PathArguments::None,
107 },
108 PathSegment {
109 ident: Ident::new("borrow", span),
110 arguments: PathArguments::None,
111 },
112 PathSegment {
113 ident: Ident::new("Cow", span),
114 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
115 colon2_token: None,
116 lt_token: token::Lt { spans: [span] },
117 args: [
118 GenericArgument::Lifetime(lifetime),
119 GenericArgument::Type(ty),
120 ]
121 .into_iter()
122 .collect(),
123 gt_token: token::Gt { spans: [span] },
124 }),
125 },
126 ]
127 .into_iter()
128 .collect(),
129 },
130 })
131}
132
133pub(crate) fn ncnamestr_cow_ty(ty_span: Span, lifetime: Lifetime) -> Type {
136 cow_ty(ncnamestr_ty(ty_span), lifetime)
137}
138
139pub(crate) fn from_xml_text_fn(ty: Type) -> Expr {
142 let span = ty.span();
143 Expr::Path(ExprPath {
144 attrs: Vec::new(),
145 qself: Some(QSelf {
146 lt_token: syn::token::Lt { spans: [span] },
147 ty: Box::new(ty),
148 position: 2,
149 as_token: Some(syn::token::As { span }),
150 gt_token: syn::token::Gt { spans: [span] },
151 }),
152 path: Path {
153 leading_colon: Some(syn::token::PathSep {
154 spans: [span, span],
155 }),
156 segments: [
157 PathSegment {
158 ident: Ident::new("xso", span),
159 arguments: PathArguments::None,
160 },
161 PathSegment {
162 ident: Ident::new("FromXmlText", span),
163 arguments: PathArguments::None,
164 },
165 PathSegment {
166 ident: Ident::new("from_xml_text", span),
167 arguments: PathArguments::None,
168 },
169 ]
170 .into_iter()
171 .collect(),
172 },
173 })
174}
175
176pub(crate) fn as_optional_xml_text_fn(ty: Type) -> Expr {
179 let span = ty.span();
180 Expr::Path(ExprPath {
181 attrs: Vec::new(),
182 qself: Some(QSelf {
183 lt_token: syn::token::Lt { spans: [span] },
184 ty: Box::new(ty),
185 position: 2,
186 as_token: Some(syn::token::As { span }),
187 gt_token: syn::token::Gt { spans: [span] },
188 }),
189 path: Path {
190 leading_colon: Some(syn::token::PathSep {
191 spans: [span, span],
192 }),
193 segments: [
194 PathSegment {
195 ident: Ident::new("xso", span),
196 arguments: PathArguments::None,
197 },
198 PathSegment {
199 ident: Ident::new("AsOptionalXmlText", span),
200 arguments: PathArguments::None,
201 },
202 PathSegment {
203 ident: Ident::new("as_optional_xml_text", span),
204 arguments: PathArguments::None,
205 },
206 ]
207 .into_iter()
208 .collect(),
209 },
210 })
211}
212
213pub(crate) fn default_fn(of_ty: Type) -> Expr {
216 let span = of_ty.span();
217 Expr::Path(ExprPath {
218 attrs: Vec::new(),
219 qself: Some(QSelf {
220 lt_token: syn::token::Lt { spans: [span] },
221 ty: Box::new(of_ty),
222 position: 3,
223 as_token: Some(syn::token::As { span }),
224 gt_token: syn::token::Gt { spans: [span] },
225 }),
226 path: Path {
227 leading_colon: Some(syn::token::PathSep {
228 spans: [span, span],
229 }),
230 segments: [
231 PathSegment {
232 ident: Ident::new("core", span),
233 arguments: PathArguments::None,
234 },
235 PathSegment {
236 ident: Ident::new("default", span),
237 arguments: PathArguments::None,
238 },
239 PathSegment {
240 ident: Ident::new("Default", span),
241 arguments: PathArguments::None,
242 },
243 PathSegment {
244 ident: Ident::new("default", span),
245 arguments: PathArguments::None,
246 },
247 ]
248 .into_iter()
249 .collect(),
250 },
251 })
252}
253
254pub(crate) fn string_ty(span: Span) -> Type {
256 Type::Path(TypePath {
257 qself: None,
258 path: Path {
259 leading_colon: Some(syn::token::PathSep {
260 spans: [span, span],
261 }),
262 segments: [
263 PathSegment {
264 ident: Ident::new("xso", span),
265 arguments: PathArguments::None,
266 },
267 PathSegment {
268 ident: Ident::new("exports", span),
269 arguments: PathArguments::None,
270 },
271 PathSegment {
272 ident: Ident::new("alloc", span),
273 arguments: PathArguments::None,
274 },
275 PathSegment {
276 ident: Ident::new("string", span),
277 arguments: PathArguments::None,
278 },
279 PathSegment {
280 ident: Ident::new("String", span),
281 arguments: PathArguments::None,
282 },
283 ]
284 .into_iter()
285 .collect(),
286 },
287 })
288}
289
290pub(crate) fn as_xml_text_fn(ty: Type) -> Expr {
293 let span = ty.span();
294 Expr::Path(ExprPath {
295 attrs: Vec::new(),
296 qself: Some(QSelf {
297 lt_token: syn::token::Lt { spans: [span] },
298 ty: Box::new(ty),
299 position: 2,
300 as_token: Some(syn::token::As { span }),
301 gt_token: syn::token::Gt { spans: [span] },
302 }),
303 path: Path {
304 leading_colon: Some(syn::token::PathSep {
305 spans: [span, span],
306 }),
307 segments: [
308 PathSegment {
309 ident: Ident::new("xso", span),
310 arguments: PathArguments::None,
311 },
312 PathSegment {
313 ident: Ident::new("AsXmlText", span),
314 arguments: PathArguments::None,
315 },
316 PathSegment {
317 ident: Ident::new("as_xml_text", span),
318 arguments: PathArguments::None,
319 },
320 ]
321 .into_iter()
322 .collect(),
323 },
324 })
325}
326
327fn text_codec_of(for_ty: Type, codec_span: Span) -> Path {
333 let span = codec_span;
334 Path {
335 leading_colon: Some(syn::token::PathSep {
336 spans: [span, span],
337 }),
338 segments: [
339 PathSegment {
340 ident: Ident::new("xso", span),
341 arguments: PathArguments::None,
342 },
343 PathSegment {
344 ident: Ident::new("TextCodec", span),
345 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
346 colon2_token: Some(syn::token::PathSep {
347 spans: [span, span],
348 }),
349 lt_token: syn::token::Lt { spans: [span] },
350 args: [GenericArgument::Type(for_ty)].into_iter().collect(),
351 gt_token: syn::token::Gt { spans: [span] },
352 }),
353 },
354 ]
355 .into_iter()
356 .collect(),
357 }
358}
359
360pub(crate) fn text_codec_encode_fn(for_ty: Type, codec_span: Span) -> Expr {
366 let mut path = text_codec_of(for_ty, codec_span);
367 path.segments.push(PathSegment {
368 ident: Ident::new("encode", codec_span),
369 arguments: PathArguments::None,
370 });
371 Expr::Path(ExprPath {
372 attrs: Vec::new(),
373 qself: None,
374 path,
375 })
376}
377
378pub(crate) fn text_codec_decode_fn(for_ty: Type, codec_span: Span) -> Expr {
384 let mut path = text_codec_of(for_ty, codec_span);
385 path.segments.push(PathSegment {
386 ident: Ident::new("decode", codec_span),
387 arguments: PathArguments::None,
388 });
389 Expr::Path(ExprPath {
390 attrs: Vec::new(),
391 qself: None,
392 path,
393 })
394}
395
396pub(crate) fn ref_ty(ty: Type, lifetime: Lifetime) -> Type {
398 let span = ty.span();
399 Type::Reference(TypeReference {
400 and_token: token::And { spans: [span] },
401 lifetime: Some(lifetime),
402 mutability: None,
403 elem: Box::new(ty),
404 })
405}
406
407pub(crate) fn phantom_fn_ret_ty(ty: Type) -> Type {
410 let span = ty.span();
411 Type::Path(TypePath {
412 qself: None,
413 path: Path {
414 leading_colon: Some(syn::token::PathSep {
415 spans: [span, span],
416 }),
417 segments: [
418 PathSegment {
419 ident: Ident::new("core", span),
420 arguments: PathArguments::None,
421 },
422 PathSegment {
423 ident: Ident::new("marker", span),
424 arguments: PathArguments::None,
425 },
426 PathSegment {
427 ident: Ident::new("PhantomData", span),
428 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
429 colon2_token: None,
430 lt_token: token::Lt { spans: [span] },
431 args: [GenericArgument::Type(Type::BareFn(TypeBareFn {
432 lifetimes: None,
433 unsafety: None,
434 abi: None,
435 fn_token: token::Fn { span: span },
436 paren_token: token::Paren::default(),
437 inputs: punctuated::Punctuated::default(),
438 variadic: None,
439 output: ReturnType::Type(
440 token::RArrow {
441 spans: [span, span],
442 },
443 Box::new(ty),
444 ),
445 }))]
446 .into_iter()
447 .collect(),
448 gt_token: token::Gt { spans: [span] },
449 }),
450 },
451 ]
452 .into_iter()
453 .collect(),
454 },
455 })
456}
457
458pub(crate) fn phantom_lifetime_ty(lifetime: Lifetime) -> Type {
461 let span = lifetime.span();
462 let dummy = Type::Tuple(TypeTuple {
463 paren_token: token::Paren::default(),
464 elems: punctuated::Punctuated::default(),
465 });
466 Type::Path(TypePath {
467 qself: None,
468 path: Path {
469 leading_colon: Some(syn::token::PathSep {
470 spans: [span, span],
471 }),
472 segments: [
473 PathSegment {
474 ident: Ident::new("core", span),
475 arguments: PathArguments::None,
476 },
477 PathSegment {
478 ident: Ident::new("marker", span),
479 arguments: PathArguments::None,
480 },
481 PathSegment {
482 ident: Ident::new("PhantomData", span),
483 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
484 colon2_token: None,
485 lt_token: token::Lt { spans: [span] },
486 args: [GenericArgument::Type(ref_ty(dummy, lifetime))]
487 .into_iter()
488 .collect(),
489 gt_token: token::Gt { spans: [span] },
490 }),
491 },
492 ]
493 .into_iter()
494 .collect(),
495 },
496 })
497}
498
499pub(crate) fn from_xml_trait(span: Span) -> Path {
500 Path {
501 leading_colon: Some(syn::token::PathSep {
502 spans: [span, span],
503 }),
504 segments: [
505 PathSegment {
506 ident: Ident::new("xso", span),
507 arguments: PathArguments::None,
508 },
509 PathSegment {
510 ident: Ident::new("FromXml", span),
511 arguments: PathArguments::None,
512 },
513 ]
514 .into_iter()
515 .collect(),
516 }
517}
518
519pub(crate) fn as_xml_trait(span: Span) -> Path {
520 Path {
521 leading_colon: Some(syn::token::PathSep {
522 spans: [span, span],
523 }),
524 segments: [
525 PathSegment {
526 ident: Ident::new("xso", span),
527 arguments: PathArguments::None,
528 },
529 PathSegment {
530 ident: Ident::new("AsXml", span),
531 arguments: PathArguments::None,
532 },
533 ]
534 .into_iter()
535 .collect(),
536 }
537}
538
539pub(crate) fn from_xml_text_trait(span: Span) -> Path {
540 Path {
541 leading_colon: Some(syn::token::PathSep {
542 spans: [span, span],
543 }),
544 segments: [
545 PathSegment {
546 ident: Ident::new("xso", span),
547 arguments: PathArguments::None,
548 },
549 PathSegment {
550 ident: Ident::new("FromXmlText", span),
551 arguments: PathArguments::None,
552 },
553 ]
554 .into_iter()
555 .collect(),
556 }
557}
558
559pub(crate) fn as_xml_text_trait(span: Span) -> Path {
560 Path {
561 leading_colon: Some(syn::token::PathSep {
562 spans: [span, span],
563 }),
564 segments: [
565 PathSegment {
566 ident: Ident::new("xso", span),
567 arguments: PathArguments::None,
568 },
569 PathSegment {
570 ident: Ident::new("AsXmlText", span),
571 arguments: PathArguments::None,
572 },
573 ]
574 .into_iter()
575 .collect(),
576 }
577}
578
579pub(crate) fn as_optional_xml_text_trait(span: Span) -> Path {
580 Path {
581 leading_colon: Some(syn::token::PathSep {
582 spans: [span, span],
583 }),
584 segments: [
585 PathSegment {
586 ident: Ident::new("xso", span),
587 arguments: PathArguments::None,
588 },
589 PathSegment {
590 ident: Ident::new("AsOptionalXmlText", span),
591 arguments: PathArguments::None,
592 },
593 ]
594 .into_iter()
595 .collect(),
596 }
597}
598
599fn from_xml_of(of_ty: Type) -> (Span, TypePath) {
602 let span = of_ty.span();
603 (
604 span,
605 TypePath {
606 qself: Some(QSelf {
607 lt_token: syn::token::Lt { spans: [span] },
608 ty: Box::new(of_ty),
609 position: 2,
610 as_token: Some(syn::token::As { span }),
611 gt_token: syn::token::Gt { spans: [span] },
612 }),
613 path: from_xml_trait(span),
614 },
615 )
616}
617
618pub(crate) fn from_xml_builder_ty(of_ty: Type) -> Type {
621 let (span, mut ty) = from_xml_of(of_ty);
622 ty.path.segments.push(PathSegment {
623 ident: Ident::new("Builder", span),
624 arguments: PathArguments::None,
625 });
626 Type::Path(ty)
627}
628
629pub(crate) fn from_events_fn(of_ty: Type) -> Expr {
632 let (span, mut ty) = from_xml_of(of_ty);
633 ty.path.segments.push(PathSegment {
634 ident: Ident::new("from_events", span),
635 arguments: PathArguments::None,
636 });
637 Expr::Path(ExprPath {
638 attrs: Vec::new(),
639 qself: ty.qself,
640 path: ty.path,
641 })
642}
643
644pub(crate) fn option_ty(ty: Type) -> Type {
647 let span = ty.span();
648 Type::Path(TypePath {
649 qself: None,
650 path: Path {
651 leading_colon: Some(syn::token::PathSep {
652 spans: [span, span],
653 }),
654 segments: [
655 PathSegment {
656 ident: Ident::new("core", span),
657 arguments: PathArguments::None,
658 },
659 PathSegment {
660 ident: Ident::new("option", span),
661 arguments: PathArguments::None,
662 },
663 PathSegment {
664 ident: Ident::new("Option", span),
665 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
666 colon2_token: None,
667 lt_token: syn::token::Lt { spans: [span] },
668 args: [GenericArgument::Type(ty)].into_iter().collect(),
669 gt_token: syn::token::Gt { spans: [span] },
670 }),
671 },
672 ]
673 .into_iter()
674 .collect(),
675 },
676 })
677}
678
679fn from_events_builder_of(of_ty: Type) -> (Span, TypePath) {
682 let span = of_ty.span();
683 (
684 span,
685 TypePath {
686 qself: Some(QSelf {
687 lt_token: syn::token::Lt { spans: [span] },
688 ty: Box::new(of_ty),
689 position: 2,
690 as_token: Some(syn::token::As { span }),
691 gt_token: syn::token::Gt { spans: [span] },
692 }),
693 path: Path {
694 leading_colon: Some(syn::token::PathSep {
695 spans: [span, span],
696 }),
697 segments: [
698 PathSegment {
699 ident: Ident::new("xso", span),
700 arguments: PathArguments::None,
701 },
702 PathSegment {
703 ident: Ident::new("FromEventsBuilder", span),
704 arguments: PathArguments::None,
705 },
706 ]
707 .into_iter()
708 .collect(),
709 },
710 },
711 )
712}
713
714pub(crate) fn feed_fn(of_ty: Type) -> Expr {
717 let (span, mut ty) = from_events_builder_of(of_ty);
718 ty.path.segments.push(PathSegment {
719 ident: Ident::new("feed", span),
720 arguments: PathArguments::None,
721 });
722 Expr::Path(ExprPath {
723 attrs: Vec::new(),
724 qself: ty.qself,
725 path: ty.path,
726 })
727}
728
729fn as_xml_of(of_ty: Type) -> (Span, TypePath) {
730 let span = of_ty.span();
731 (
732 span,
733 TypePath {
734 qself: Some(QSelf {
735 lt_token: syn::token::Lt { spans: [span] },
736 ty: Box::new(of_ty),
737 position: 2,
738 as_token: Some(syn::token::As { span }),
739 gt_token: syn::token::Gt { spans: [span] },
740 }),
741 path: as_xml_trait(span),
742 },
743 )
744}
745
746pub(crate) fn as_xml_iter_fn(of_ty: Type) -> Expr {
749 let (span, mut ty) = as_xml_of(of_ty);
750 ty.path.segments.push(PathSegment {
751 ident: Ident::new("as_xml_iter", span),
752 arguments: PathArguments::None,
753 });
754 Expr::Path(ExprPath {
755 attrs: Vec::new(),
756 qself: ty.qself,
757 path: ty.path,
758 })
759}
760
761pub(crate) fn item_iter_ty(of_ty: Type, lifetime: Lifetime) -> Type {
764 let (span, mut ty) = as_xml_of(of_ty);
765 ty.path.segments.push(PathSegment {
766 ident: Ident::new("ItemIter", span),
767 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
768 colon2_token: None,
769 lt_token: token::Lt { spans: [span] },
770 args: [GenericArgument::Lifetime(lifetime)].into_iter().collect(),
771 gt_token: token::Gt { spans: [span] },
772 }),
773 });
774 Type::Path(ty)
775}
776
777fn into_iterator_of(of_ty: Type) -> (Span, TypePath) {
779 let span = of_ty.span();
780 (
781 span,
782 TypePath {
783 qself: Some(QSelf {
784 lt_token: syn::token::Lt { spans: [span] },
785 ty: Box::new(of_ty),
786 position: 3,
787 as_token: Some(syn::token::As { span }),
788 gt_token: syn::token::Gt { spans: [span] },
789 }),
790 path: Path {
791 leading_colon: Some(syn::token::PathSep {
792 spans: [span, span],
793 }),
794 segments: [
795 PathSegment {
796 ident: Ident::new("core", span),
797 arguments: PathArguments::None,
798 },
799 PathSegment {
800 ident: Ident::new("iter", span),
801 arguments: PathArguments::None,
802 },
803 PathSegment {
804 ident: Ident::new("IntoIterator", span),
805 arguments: PathArguments::None,
806 },
807 ]
808 .into_iter()
809 .collect(),
810 },
811 },
812 )
813}
814
815pub(crate) fn into_iterator_iter_ty(of_ty: Type) -> Type {
818 let (span, mut ty) = into_iterator_of(of_ty);
819 ty.path.segments.push(PathSegment {
820 ident: Ident::new("IntoIter", span),
821 arguments: PathArguments::None,
822 });
823 Type::Path(ty)
824}
825
826pub(crate) fn into_iterator_item_ty(of_ty: Type) -> Type {
829 let (span, mut ty) = into_iterator_of(of_ty);
830 ty.path.segments.push(PathSegment {
831 ident: Ident::new("Item", span),
832 arguments: PathArguments::None,
833 });
834 Type::Path(ty)
835}
836
837pub(crate) fn into_iterator_into_iter_fn(of_ty: Type) -> Expr {
840 let (span, mut ty) = into_iterator_of(of_ty);
841 ty.path.segments.push(PathSegment {
842 ident: Ident::new("into_iter", span),
843 arguments: PathArguments::None,
844 });
845 Expr::Path(ExprPath {
846 attrs: Vec::new(),
847 qself: ty.qself,
848 path: ty.path,
849 })
850}
851
852pub(crate) fn extend_fn(of_ty: Type, item_ty: Type) -> Expr {
855 let span = of_ty.span();
856 Expr::Path(ExprPath {
857 attrs: Vec::new(),
858 qself: Some(QSelf {
859 lt_token: syn::token::Lt { spans: [span] },
860 ty: Box::new(of_ty),
861 position: 3,
862 as_token: Some(syn::token::As { span }),
863 gt_token: syn::token::Gt { spans: [span] },
864 }),
865 path: Path {
866 leading_colon: Some(syn::token::PathSep {
867 spans: [span, span],
868 }),
869 segments: [
870 PathSegment {
871 ident: Ident::new("core", span),
872 arguments: PathArguments::None,
873 },
874 PathSegment {
875 ident: Ident::new("iter", span),
876 arguments: PathArguments::None,
877 },
878 PathSegment {
879 ident: Ident::new("Extend", span),
880 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
881 colon2_token: Some(syn::token::PathSep {
882 spans: [span, span],
883 }),
884 lt_token: syn::token::Lt { spans: [span] },
885 args: [GenericArgument::Type(item_ty)].into_iter().collect(),
886 gt_token: syn::token::Gt { spans: [span] },
887 }),
888 },
889 PathSegment {
890 ident: Ident::new("extend", span),
891 arguments: PathArguments::None,
892 },
893 ]
894 .into_iter()
895 .collect(),
896 },
897 })
898}
899
900pub(crate) fn option_as_xml_ty(inner_ty: Type) -> Type {
902 let span = inner_ty.span();
903 Type::Path(TypePath {
904 qself: None,
905 path: Path {
906 leading_colon: Some(syn::token::PathSep {
907 spans: [span, span],
908 }),
909 segments: [
910 PathSegment {
911 ident: Ident::new("xso", span),
912 arguments: PathArguments::None,
913 },
914 PathSegment {
915 ident: Ident::new("asxml", span),
916 arguments: PathArguments::None,
917 },
918 PathSegment {
919 ident: Ident::new("OptionAsXml", span),
920 arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
921 colon2_token: None,
922 lt_token: token::Lt { spans: [span] },
923 args: [GenericArgument::Type(inner_ty)].into_iter().collect(),
924 gt_token: token::Gt { spans: [span] },
925 }),
926 },
927 ]
928 .into_iter()
929 .collect(),
930 },
931 })
932}
933
934#[cfg(feature = "minidom")]
936pub(crate) fn element_ty(span: Span) -> Type {
937 Type::Path(TypePath {
938 qself: None,
939 path: Path {
940 leading_colon: Some(syn::token::PathSep {
941 spans: [span, span],
942 }),
943 segments: [
944 PathSegment {
945 ident: Ident::new("xso", span),
946 arguments: PathArguments::None,
947 },
948 PathSegment {
949 ident: Ident::new("exports", span),
950 arguments: PathArguments::None,
951 },
952 PathSegment {
953 ident: Ident::new("minidom", span),
954 arguments: PathArguments::None,
955 },
956 PathSegment {
957 ident: Ident::new("Element", span),
958 arguments: PathArguments::None,
959 },
960 ]
961 .into_iter()
962 .collect(),
963 },
964 })
965}
966
967pub(crate) fn unknown_attribute_policy_path(span: Span) -> Path {
969 Path {
970 leading_colon: Some(syn::token::PathSep {
971 spans: [span, span],
972 }),
973 segments: [
974 PathSegment {
975 ident: Ident::new("xso", span),
976 arguments: PathArguments::None,
977 },
978 PathSegment {
979 ident: Ident::new("UnknownAttributePolicy", span),
980 arguments: PathArguments::None,
981 },
982 ]
983 .into_iter()
984 .collect(),
985 }
986}
987
988pub(crate) fn unknown_child_policy_path(span: Span) -> Path {
990 Path {
991 leading_colon: Some(syn::token::PathSep {
992 spans: [span, span],
993 }),
994 segments: [
995 PathSegment {
996 ident: Ident::new("xso", span),
997 arguments: PathArguments::None,
998 },
999 PathSegment {
1000 ident: Ident::new("UnknownChildPolicy", span),
1001 arguments: PathArguments::None,
1002 },
1003 ]
1004 .into_iter()
1005 .collect(),
1006 }
1007}
1008
1009pub(crate) fn discard_builder_ty(span: Span) -> Type {
1011 Type::Path(TypePath {
1012 qself: None,
1013 path: Path {
1014 leading_colon: Some(syn::token::PathSep {
1015 spans: [span, span],
1016 }),
1017 segments: [
1018 PathSegment {
1019 ident: Ident::new("xso", span),
1020 arguments: PathArguments::None,
1021 },
1022 PathSegment {
1023 ident: Ident::new("fromxml", span),
1024 arguments: PathArguments::None,
1025 },
1026 PathSegment {
1027 ident: Ident::new("Discard", span),
1028 arguments: PathArguments::None,
1029 },
1030 ]
1031 .into_iter()
1032 .collect(),
1033 },
1034 })
1035}
1036
1037pub(crate) fn bool_ty(span: Span) -> Type {
1043 Type::Path(TypePath {
1044 qself: None,
1045 path: Path {
1046 leading_colon: Some(syn::token::PathSep {
1047 spans: [span, span],
1048 }),
1049 segments: [
1050 PathSegment {
1051 ident: Ident::new("xso", span),
1052 arguments: PathArguments::None,
1053 },
1054 PathSegment {
1055 ident: Ident::new("exports", span),
1056 arguments: PathArguments::None,
1057 },
1058 PathSegment {
1059 ident: Ident::new("CoreBool", span),
1060 arguments: PathArguments::None,
1061 },
1062 ]
1063 .into_iter()
1064 .collect(),
1065 },
1066 })
1067}
1068
1069pub(crate) fn u8_ty(span: Span) -> Type {
1075 Type::Path(TypePath {
1076 qself: None,
1077 path: Path {
1078 leading_colon: Some(syn::token::PathSep {
1079 spans: [span, span],
1080 }),
1081 segments: [
1082 PathSegment {
1083 ident: Ident::new("xso", span),
1084 arguments: PathArguments::None,
1085 },
1086 PathSegment {
1087 ident: Ident::new("exports", span),
1088 arguments: PathArguments::None,
1089 },
1090 PathSegment {
1091 ident: Ident::new("CoreU8", span),
1092 arguments: PathArguments::None,
1093 },
1094 ]
1095 .into_iter()
1096 .collect(),
1097 },
1098 })
1099}
1100
1101pub(crate) fn empty_builder_ty(span: Span) -> Type {
1103 Type::Path(TypePath {
1104 qself: None,
1105 path: Path {
1106 leading_colon: Some(syn::token::PathSep {
1107 spans: [span, span],
1108 }),
1109 segments: [
1110 PathSegment {
1111 ident: Ident::new("xso", span),
1112 arguments: PathArguments::None,
1113 },
1114 PathSegment {
1115 ident: Ident::new("fromxml", span),
1116 arguments: PathArguments::None,
1117 },
1118 PathSegment {
1119 ident: Ident::new("EmptyBuilder", span),
1120 arguments: PathArguments::None,
1121 },
1122 ]
1123 .into_iter()
1124 .collect(),
1125 },
1126 })
1127}
1128
1129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1130pub(crate) enum ReferencedIdent<'x> {
1131 Lifetime(&'x Ident),
1132 Name(&'x Ident),
1133}
1134
1135pub(crate) fn iter_referenced_names_in_bound<'a, F: FnMut(ReferencedIdent<'a>) -> Result<()>>(
1136 bound: &'a TypeParamBound,
1137 f: &mut F,
1138) -> Result<()> {
1139 match bound {
1140 TypeParamBound::Trait(bound) => {
1141 if let Some(lifetimes) = bound.lifetimes.as_ref() {
1142 return Err(Error::new_spanned(
1143 lifetimes,
1144 "use of higher-rank trait bounds is not supported",
1145 ));
1146 }
1147 iter_referenced_names_in_path(&bound.path, f)?;
1148 }
1149 TypeParamBound::Lifetime(bound) => {
1150 f(ReferencedIdent::Lifetime(&bound.ident))?;
1151 }
1152 other => {
1153 return Err(Error::new_spanned(
1154 other,
1155 "this kind of type parameter bound is not supported",
1156 ))
1157 }
1158 }
1159 Ok(())
1160}
1161
1162pub(crate) fn iter_referenced_names_in_generic_param<
1163 'a,
1164 F: FnMut(ReferencedIdent<'a>) -> Result<()>,
1165>(
1166 param: &'a GenericParam,
1167 f: &mut F,
1168) -> Result<()> {
1169 match param {
1170 GenericParam::Lifetime(param) => {
1171 for bound in param.bounds.iter() {
1172 f(ReferencedIdent::Lifetime(&bound.ident))?;
1173 }
1174 }
1175 GenericParam::Type(param) => {
1176 for bound in param.bounds.iter() {
1177 iter_referenced_names_in_bound(bound, f)?;
1178 }
1179 if let Some(default) = param.default.as_ref() {
1180 iter_referenced_names_in_ty(default, f)?;
1181 }
1182 }
1183 GenericParam::Const(param) => {
1184 iter_referenced_names_in_ty(¶m.ty, f)?;
1185 if let Some(default) = param.default.as_ref() {
1186 iter_referenced_names_in_expr(default, f)?;
1187 }
1188 }
1189 }
1190 Ok(())
1191}
1192
1193pub(crate) fn iter_referenced_names_in_ty<'a, F: FnMut(ReferencedIdent<'a>) -> Result<()>>(
1194 ty: &'a Type,
1195 f: &mut F,
1196) -> Result<()> {
1197 match ty {
1198 Type::Array(ty) => iter_referenced_names_in_ty(&ty.elem, f)?,
1199 Type::BareFn(ty) => {
1200 match ty.output {
1201 ReturnType::Type(_, ref ty) => iter_referenced_names_in_ty(ty, f)?,
1202 ReturnType::Default => (),
1203 }
1204
1205 for input in ty.inputs.iter() {
1206 iter_referenced_names_in_ty(&input.ty, f)?;
1207 }
1208 }
1209 Type::Group(ty) => iter_referenced_names_in_ty(&ty.elem, f)?,
1210 Type::ImplTrait(ty) => {
1211 for bound in ty.bounds.iter() {
1212 iter_referenced_names_in_bound(&bound, f)?;
1213 }
1214 }
1215 Type::Infer(_) => (),
1216 Type::Never(_) => (),
1217 Type::Paren(ty) => iter_referenced_names_in_ty(&ty.elem, f)?,
1218 Type::Path(ty) => {
1219 if let Some(qself) = ty.qself.as_ref() {
1220 iter_referenced_names_in_ty(&qself.ty, f)?;
1221 }
1222 iter_referenced_names_in_path(&ty.path, f)?;
1223 }
1224 Type::Ptr(ty) => iter_referenced_names_in_ty(&ty.elem, f)?,
1225 Type::Reference(ty) => {
1226 if let Some(lifetime) = ty.lifetime.as_ref() {
1227 f(ReferencedIdent::Lifetime(&lifetime.ident))?;
1228 }
1229 iter_referenced_names_in_ty(&ty.elem, f)?;
1230 }
1231 Type::Slice(ty) => iter_referenced_names_in_ty(&ty.elem, f)?,
1232 Type::TraitObject(ty) => {
1233 for bound in ty.bounds.iter() {
1234 iter_referenced_names_in_bound(&bound, f)?;
1235 }
1236 }
1237 Type::Tuple(ty) => {
1238 for elem in ty.elems.iter() {
1239 iter_referenced_names_in_ty(elem, f)?;
1240 }
1241 }
1242 other => {
1243 return Err(Error::new_spanned(
1244 other,
1245 "this kind of type is not supported",
1246 ))
1247 }
1248 }
1249 Ok(())
1250}
1251
1252fn iter_referenced_names_in_angle_bracketed_generic_arguments<
1253 'a,
1254 F: FnMut(ReferencedIdent<'a>) -> Result<()>,
1255>(
1256 args: &'a AngleBracketedGenericArguments,
1257 f: &mut F,
1258) -> Result<()> {
1259 for arg in args.args.iter() {
1260 match arg {
1261 GenericArgument::Lifetime(arg) => f(ReferencedIdent::Name(&arg.ident))?,
1262 GenericArgument::Type(arg) => iter_referenced_names_in_ty(&arg, f)?,
1263 GenericArgument::Const(arg) => iter_referenced_names_in_expr(&arg, f)?,
1264 GenericArgument::AssocType(arg) => iter_referenced_names_in_ty(&arg.ty, f)?,
1265 GenericArgument::AssocConst(arg) => iter_referenced_names_in_expr(&arg.value, f)?,
1266 GenericArgument::Constraint(arg) => {
1267 for bound in arg.bounds.iter() {
1268 iter_referenced_names_in_bound(&bound, f)?;
1269 }
1270 }
1271 other => {
1272 return Err(Error::new_spanned(
1273 other,
1274 "this kind of generic argument is not supported",
1275 ))
1276 }
1277 }
1278 }
1279 Ok(())
1280}
1281
1282pub(crate) fn iter_referenced_names_in_path<'a, F: FnMut(ReferencedIdent<'a>) -> Result<()>>(
1283 path: &'a Path,
1284 f: &mut F,
1285) -> Result<()> {
1286 if path.leading_colon.is_none() {
1287 if let Some(first) = path.segments.first() {
1289 f(ReferencedIdent::Name(&first.ident))?;
1290 }
1291 }
1292
1293 for segment in path.segments.iter() {
1294 match segment.arguments {
1295 PathArguments::None => (),
1296 PathArguments::AngleBracketed(ref arguments) => {
1297 iter_referenced_names_in_angle_bracketed_generic_arguments(&arguments, f)?;
1298 }
1299 PathArguments::Parenthesized(ref arguments) => {
1300 for arg in arguments.inputs.iter() {
1301 iter_referenced_names_in_ty(&arg, f)?;
1302 }
1303 match arguments.output {
1304 ReturnType::Type(_, ref ty) => iter_referenced_names_in_ty(&ty, f)?,
1305 ReturnType::Default => (),
1306 }
1307 }
1308 }
1309 }
1310 Ok(())
1311}
1312
1313pub(crate) fn iter_referenced_names_in_stmt<'a, F: FnMut(ReferencedIdent<'a>) -> Result<()>>(
1314 stmt: &'a Stmt,
1315 f: &mut F,
1316) -> Result<()> {
1317 match stmt {
1318 Stmt::Expr(expr, _) => {
1319 iter_referenced_names_in_expr(&expr, f)?;
1320 }
1321 other => {
1322 return Err(Error::new_spanned(
1323 other,
1324 "this kind of statement is not supported",
1325 ))
1326 }
1327 }
1328 Ok(())
1329}
1330
1331pub(crate) fn iter_referenced_names_in_expr<'a, F: FnMut(ReferencedIdent<'a>) -> Result<()>>(
1332 expr: &'a Expr,
1333 f: &mut F,
1334) -> Result<()> {
1335 match expr {
1336 Expr::Array(expr) => {
1337 for elem in expr.elems.iter() {
1338 iter_referenced_names_in_expr(&elem, f)?;
1339 }
1340 }
1341 Expr::Binary(expr) => {
1342 iter_referenced_names_in_expr(&expr.left, f)?;
1343 iter_referenced_names_in_expr(&expr.right, f)?;
1344 }
1345 Expr::Block(expr) => {
1346 for stmt in expr.block.stmts.iter() {
1347 iter_referenced_names_in_stmt(&stmt, f)?;
1348 }
1349 }
1350 Expr::Break(_) => (),
1351 Expr::Call(expr) => {
1352 iter_referenced_names_in_expr(&expr.func, f)?;
1353 for arg in expr.args.iter() {
1354 iter_referenced_names_in_expr(&arg, f)?;
1355 }
1356 }
1357 Expr::Cast(expr) => {
1358 iter_referenced_names_in_expr(&expr.expr, f)?;
1359 iter_referenced_names_in_ty(&expr.ty, f)?;
1360 }
1361 Expr::Const(expr) => {
1363 for stmt in expr.block.stmts.iter() {
1364 iter_referenced_names_in_stmt(&stmt, f)?;
1365 }
1366 }
1367 Expr::Continue(_) => (),
1368 Expr::Field(expr) => {
1369 iter_referenced_names_in_expr(&expr.base, f)?;
1370 }
1371 Expr::Group(expr) => {
1373 iter_referenced_names_in_expr(&expr.expr, f)?;
1374 }
1375 Expr::If(expr) => {
1376 iter_referenced_names_in_expr(&expr.cond, f)?;
1377 for stmt in expr.then_branch.stmts.iter() {
1378 iter_referenced_names_in_stmt(&stmt, f)?;
1379 }
1380 if let Some(else_branch) = expr.else_branch.as_ref() {
1381 iter_referenced_names_in_expr(&else_branch.1, f)?;
1382 }
1383 }
1384 Expr::Index(expr) => {
1385 iter_referenced_names_in_expr(&expr.expr, f)?;
1386 }
1387 Expr::Lit(_) => (),
1389 Expr::Loop(expr) => {
1390 for stmt in expr.body.stmts.iter() {
1391 iter_referenced_names_in_stmt(&stmt, f)?;
1392 }
1393 }
1394 Expr::MethodCall(expr) => {
1396 iter_referenced_names_in_expr(&expr.receiver, f)?;
1397 iter_referenced_names_in_expr(&expr.receiver, f)?;
1398 }
1399 other => {
1400 return Err(Error::new_spanned(
1401 other,
1402 "this kind of expression is not supported",
1403 ))
1404 }
1405 }
1406 Ok(())
1407}