syn_utils/
enum_variant.rs

1use crate::*;
2
3pub trait EnumVariant {
4  fn has_single_item(&self) -> bool;
5  fn is_unit(&self) -> bool;
6  fn type_(&self) -> syn::Result<&Type>;
7  fn type_mut(&mut self) -> syn::Result<&mut Type>;
8  fn type_path(&self) -> syn::Result<&Path>;
9  fn type_path_mut(&mut self) -> syn::Result<&mut Path>;
10  fn named_fields(&self) -> syn::Result<&Punctuated<Field, Token![,]>>;
11  fn named_fields_mut(&mut self) -> syn::Result<&mut Punctuated<Field, Token![,]>>;
12  fn unnamed_fields(&self) -> syn::Result<&Punctuated<Field, Token![,]>>;
13  fn unnamed_fields_mut(&mut self) -> syn::Result<&mut Punctuated<Field, Token![,]>>;
14}
15
16impl EnumVariant for Variant {
17  fn has_single_item(&self) -> bool {
18    if let Fields::Unnamed(fields) = &self.fields && fields.unnamed.len() == 1 {
19      true
20    } else {
21      false
22    }
23  }
24
25  fn type_path_mut(&mut self) -> syn::Result<&mut Path> {
26    let span = self.span();
27
28    if let Fields::Unnamed(fields) = &mut self.fields && fields.unnamed.len() == 1 {
29      Ok(fields.unnamed.last_mut().unwrap().ty.as_path_mut()?)
30    } else {
31      bail_with_span!(span, "Expected this variant to have a single unnamed field");
32    }
33  }
34
35  /// Returns a mutable ref to the type of the enum variant, if the variant contains only a single unnamed field.
36  fn type_mut(&mut self) -> syn::Result<&mut Type> {
37    let span = self.span();
38
39    if let Fields::Unnamed(fields) = &mut self.fields && fields.unnamed.len() == 1 {
40      Ok(&mut fields.unnamed.last_mut().unwrap().ty)
41    } else {
42      bail_with_span!(span, "Expected this variant to have a single unnamed field");
43    }
44  }
45
46  fn type_path(&self) -> syn::Result<&Path> {
47    if let Fields::Unnamed(fields) = &self.fields && fields.unnamed.len() == 1 {
48      Ok(fields.unnamed.last().unwrap().ty.as_path()?)
49    } else {
50      bail!(self, "Expected this variant to have a single unnamed field");
51    }
52  }
53
54  /// Returns the type of the enum variant, if the variant contains only a single unnamed field.
55  fn type_(&self) -> syn::Result<&Type> {
56    if let Fields::Unnamed(fields) = &self.fields && fields.unnamed.len() == 1 {
57      Ok(&fields.unnamed.last().unwrap().ty)
58    } else {
59      bail!(self, "Expected this variant to have a single unnamed field");
60    }
61  }
62
63  fn is_unit(&self) -> bool {
64    matches!(self.fields, Fields::Unit)
65  }
66
67  fn named_fields(&self) -> syn::Result<&Punctuated<Field, Token![,]>> {
68    if let Fields::Named(fields) = &self.fields {
69      Ok(&fields.named)
70    } else {
71      bail!(self, "Expected this variant to have named fields");
72    }
73  }
74
75  fn named_fields_mut(&mut self) -> syn::Result<&mut Punctuated<Field, Token![,]>> {
76    let span = self.span();
77
78    if let Fields::Named(fields) = &mut self.fields {
79      Ok(&mut fields.named)
80    } else {
81      bail_with_span!(span, "Expected this variant to have named fields");
82    }
83  }
84
85  fn unnamed_fields(&self) -> syn::Result<&Punctuated<Field, token::Comma>> {
86    if let Fields::Unnamed(fields) = &self.fields {
87      Ok(&fields.unnamed)
88    } else {
89      bail!(self, "Expected this variant to have unnamed fields");
90    }
91  }
92
93  fn unnamed_fields_mut(&mut self) -> syn::Result<&mut Punctuated<Field, Token![,]>> {
94    let span = self.span();
95
96    if let Fields::Unnamed(fields) = &mut self.fields {
97      Ok(&mut fields.unnamed)
98    } else {
99      bail_with_span!(span, "Expected this variant to have unnamed fields");
100    }
101  }
102}