1mod builder;
4pub mod variant;
5
6pub use builder::Builder;
7pub use variant::Variant;
8
9pub enum Error {
11 UnsupportedExpression(syn::Expr),
13
14 UnsupportedExpressionLiteral(syn::ExprLit),
16}
17
18impl std::fmt::Debug for Error {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 Self::UnsupportedExpression(_) => f.debug_tuple("UnsupportedExpression").finish(),
22 Self::UnsupportedExpressionLiteral(_) => {
23 f.debug_tuple("UnsupportedExpressionLiteral").finish()
24 }
25 }
26 }
27}
28
29impl std::fmt::Display for Error {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 Error::UnsupportedExpression(_) => {
33 write!(f, "unsupported doc attribute expression")
34 }
35 Error::UnsupportedExpressionLiteral(_) => {
36 write!(f, "unsupported doc attribute literal")
37 }
38 }
39 }
40}
41
42impl std::error::Error for Error {}
43
44pub type Result<T> = std::result::Result<T, Error>;
46
47#[derive(Debug)]
49pub struct Enum {
50 identifier: String,
51
52 documentation: Option<String>,
53}
54
55impl Enum {
56 pub fn new(identifier: String, documentation: Option<String>) -> Self {
69 Self {
70 identifier,
71 documentation,
72 }
73 }
74
75 pub fn identifier(&self) -> &str {
92 self.identifier.as_str()
93 }
94
95 pub fn documentation(&self) -> Option<&str> {
112 self.documentation.as_deref()
113 }
114}
115
116impl std::fmt::Display for Enum {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 write!(f, "::introspect::Enum::new(")?;
119 write!(f, "r#\"{}\"#.into(), ", self.identifier)?;
120
121 match self.documentation.as_ref() {
122 Some(documentation) => write!(f, "Some(r#\"{}\"#.into())", documentation)?,
123 None => write!(f, "None")?,
124 };
125
126 write!(f, ")")
127 }
128}
129
130impl TryFrom<&syn::ItemEnum> for Enum {
131 type Error = Error;
132
133 fn try_from(value: &syn::ItemEnum) -> Result<Self> {
134 let documentation = value
135 .attrs
136 .iter()
137 .filter_map(|attr| match attr.meta.require_name_value() {
138 Ok(v) => Some(v),
139 Err(_) => None,
140 })
141 .filter_map(|enum_| {
142 enum_
143 .path
144 .get_ident()
145 .map(|ident| (ident, enum_.value.clone()))
146 })
147 .filter(|(ident, _)| *ident == "doc")
148 .map(|(_, expr)| match expr {
149 syn::Expr::Lit(expr_lit) => match expr_lit.lit {
150 syn::Lit::Str(lit_str) => Ok(lit_str.value().trim().to_string()),
151 _ => Err(Error::UnsupportedExpressionLiteral(expr_lit)),
152 },
153 _ => Err(Error::UnsupportedExpression(expr)),
154 })
155 .collect::<Result<Vec<String>>>()?
156 .join("\n");
157
158 Ok(Self {
159 identifier: value.ident.to_string(),
160 documentation: match documentation.is_empty() {
161 true => None,
162 false => Some(documentation),
163 },
164 })
165 }
166}