1 use crate::ast::{Enum, Field, Struct, Variant};
2 use syn::{Member, Type};
3
4 impl Struct<'_> {
from_field(&self) -> Option<&Field>5 pub(crate) fn from_field(&self) -> Option<&Field> {
6 from_field(&self.fields)
7 }
8
source_field(&self) -> Option<&Field>9 pub(crate) fn source_field(&self) -> Option<&Field> {
10 source_field(&self.fields)
11 }
12
backtrace_field(&self) -> Option<&Field>13 pub(crate) fn backtrace_field(&self) -> Option<&Field> {
14 backtrace_field(&self.fields)
15 }
16
distinct_backtrace_field(&self) -> Option<&Field>17 pub(crate) fn distinct_backtrace_field(&self) -> Option<&Field> {
18 let backtrace_field = self.backtrace_field()?;
19 distinct_backtrace_field(backtrace_field, self.from_field())
20 }
21 }
22
23 impl Enum<'_> {
has_source(&self) -> bool24 pub(crate) fn has_source(&self) -> bool {
25 self.variants
26 .iter()
27 .any(|variant| variant.source_field().is_some() || variant.attrs.transparent.is_some())
28 }
29
has_backtrace(&self) -> bool30 pub(crate) fn has_backtrace(&self) -> bool {
31 self.variants
32 .iter()
33 .any(|variant| variant.backtrace_field().is_some())
34 }
35
has_display(&self) -> bool36 pub(crate) fn has_display(&self) -> bool {
37 self.attrs.display.is_some()
38 || self.attrs.transparent.is_some()
39 || self
40 .variants
41 .iter()
42 .any(|variant| variant.attrs.display.is_some())
43 || self
44 .variants
45 .iter()
46 .all(|variant| variant.attrs.transparent.is_some())
47 }
48 }
49
50 impl Variant<'_> {
from_field(&self) -> Option<&Field>51 pub(crate) fn from_field(&self) -> Option<&Field> {
52 from_field(&self.fields)
53 }
54
source_field(&self) -> Option<&Field>55 pub(crate) fn source_field(&self) -> Option<&Field> {
56 source_field(&self.fields)
57 }
58
backtrace_field(&self) -> Option<&Field>59 pub(crate) fn backtrace_field(&self) -> Option<&Field> {
60 backtrace_field(&self.fields)
61 }
62
distinct_backtrace_field(&self) -> Option<&Field>63 pub(crate) fn distinct_backtrace_field(&self) -> Option<&Field> {
64 let backtrace_field = self.backtrace_field()?;
65 distinct_backtrace_field(backtrace_field, self.from_field())
66 }
67 }
68
69 impl Field<'_> {
is_backtrace(&self) -> bool70 pub(crate) fn is_backtrace(&self) -> bool {
71 type_is_backtrace(self.ty)
72 }
73 }
74
from_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>>75 fn from_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> {
76 for field in fields {
77 if field.attrs.from.is_some() {
78 return Some(field);
79 }
80 }
81 None
82 }
83
source_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>>84 fn source_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> {
85 for field in fields {
86 if field.attrs.from.is_some() || field.attrs.source.is_some() {
87 return Some(field);
88 }
89 }
90 for field in fields {
91 match &field.member {
92 Member::Named(ident) if ident == "source" => return Some(field),
93 _ => {}
94 }
95 }
96 None
97 }
98
backtrace_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>>99 fn backtrace_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> {
100 for field in fields {
101 if field.attrs.backtrace.is_some() {
102 return Some(field);
103 }
104 }
105 for field in fields {
106 if field.is_backtrace() {
107 return Some(field);
108 }
109 }
110 None
111 }
112
113 // The #[backtrace] field, if it is not the same as the #[from] field.
distinct_backtrace_field<'a, 'b>( backtrace_field: &'a Field<'b>, from_field: Option<&Field>, ) -> Option<&'a Field<'b>>114 fn distinct_backtrace_field<'a, 'b>(
115 backtrace_field: &'a Field<'b>,
116 from_field: Option<&Field>,
117 ) -> Option<&'a Field<'b>> {
118 if from_field.map_or(false, |from_field| {
119 from_field.member == backtrace_field.member
120 }) {
121 None
122 } else {
123 Some(backtrace_field)
124 }
125 }
126
type_is_backtrace(ty: &Type) -> bool127 fn type_is_backtrace(ty: &Type) -> bool {
128 let path = match ty {
129 Type::Path(ty) => &ty.path,
130 _ => return false,
131 };
132
133 let last = path.segments.last().unwrap();
134 last.ident == "Backtrace" && last.arguments.is_empty()
135 }
136