sylvia_derive/types/
msg_field.rs1use crate::fold::StripSelfPath;
2use crate::parser::check_generics::{CheckGenerics, GetPath};
3use proc_macro2::TokenStream;
4use proc_macro_error::emit_error;
5use quote::quote;
6use syn::fold::Fold;
7use syn::spanned::Spanned;
8use syn::visit::Visit;
9use syn::{Attribute, Ident, Pat, PatType, Type};
10
11#[derive(Debug)]
13pub struct MsgField<'a> {
14 name: &'a Ident,
15 ty: &'a Type,
16 stripped_ty: Type,
17 attrs: &'a Vec<Attribute>,
18}
19
20impl<'a> MsgField<'a> {
21 pub fn new<Generic>(
23 item: &'a PatType,
24 generics_checker: &mut CheckGenerics<Generic>,
25 ) -> Option<MsgField<'a>>
26 where
27 Generic: GetPath + PartialEq,
28 {
29 let name = match &*item.pat {
30 Pat::Ident(p) => Some(&p.ident),
31 pat => {
32 emit_error!(pat.span(), "Expected argument name, pattern occurred");
49 None
50 }
51 }?;
52
53 let ty = &item.ty;
54 let stripped_ty = StripSelfPath.fold_type((*item.ty).clone());
55 let attrs = &item.attrs;
56 generics_checker.visit_type(&stripped_ty);
57
58 Some(Self {
59 name,
60 ty,
61 stripped_ty,
62 attrs,
63 })
64 }
65
66 pub fn emit(&self) -> TokenStream {
68 let Self {
69 name,
70 stripped_ty,
71 attrs,
72 ..
73 } = self;
74
75 quote! {
76 #(#attrs)*
77 #name: #stripped_ty
78 }
79 }
80
81 pub fn emit_pub(&self) -> TokenStream {
83 let Self {
84 name,
85 stripped_ty,
86 attrs,
87 ..
88 } = self;
89
90 quote! {
91 #(#attrs)*
92 pub #name: #stripped_ty
93 }
94 }
95
96 pub fn emit_method_field(&self) -> TokenStream {
98 let Self {
99 name, stripped_ty, ..
100 } = self;
101
102 quote! {
103 #name: #stripped_ty
104 }
105 }
106
107 pub fn emit_method_field_folded(&self) -> TokenStream {
108 let Self { name, ty, .. } = self;
109
110 quote! {
111 #name: #ty
112 }
113 }
114
115 pub fn name(&self) -> &'a Ident {
116 self.name
117 }
118
119 pub fn ty(&self) -> &'a Type {
120 self.ty
121 }
122
123 pub fn attrs(&self) -> &'a Vec<Attribute> {
124 self.attrs
125 }
126}