diplomat_core/ast/
structs.rs1use serde::Serialize;
2
3use super::docs::Docs;
4use super::{Attrs, Ident, LifetimeEnv, Method, Mutability, PathType, TypeName};
5
6#[derive(Clone, PartialEq, Eq, Hash, Serialize, Debug)]
8#[non_exhaustive]
9pub struct Struct {
10 pub name: Ident,
11 pub docs: Docs,
12 pub lifetimes: LifetimeEnv,
13 pub fields: Vec<(Ident, TypeName, Docs)>,
14 pub methods: Vec<Method>,
15 pub output_only: bool,
16 pub attrs: Attrs,
17}
18
19impl Struct {
20 pub fn new(strct: &syn::ItemStruct, output_only: bool, parent_attrs: &Attrs) -> Self {
22 let self_path_type = PathType::extract_self_type(strct);
23 let fields: Vec<_> = strct
24 .fields
25 .iter()
26 .map(|field| {
27 let name = field
29 .ident
30 .as_ref()
31 .map(Into::into)
32 .expect("non-opaque tuples structs are disallowed");
33 let type_name = TypeName::from_syn(&field.ty, Some(self_path_type.clone()));
34 let docs = Docs::from_attrs(&field.attrs);
35
36 (name, type_name, docs)
37 })
38 .collect();
39
40 let lifetimes = LifetimeEnv::from_struct_item(strct, &fields[..]);
41 let mut attrs = parent_attrs.clone();
42 attrs.add_attrs(&strct.attrs);
43 Struct {
44 name: (&strct.ident).into(),
45 docs: Docs::from_attrs(&strct.attrs),
46 lifetimes,
47 fields,
48 methods: vec![],
49 output_only,
50 attrs,
51 }
52 }
53}
54
55#[derive(Clone, Serialize, Debug, Hash, PartialEq, Eq)]
59#[non_exhaustive]
60pub struct OpaqueStruct {
61 pub name: Ident,
62 pub docs: Docs,
63 pub lifetimes: LifetimeEnv,
64 pub methods: Vec<Method>,
65 pub mutability: Mutability,
66 pub attrs: Attrs,
67}
68
69impl OpaqueStruct {
70 pub fn new(strct: &syn::ItemStruct, mutability: Mutability, parent_attrs: &Attrs) -> Self {
72 let mut attrs = parent_attrs.clone();
73 attrs.add_attrs(&strct.attrs);
74 OpaqueStruct {
75 name: Ident::from(&strct.ident),
76 docs: Docs::from_attrs(&strct.attrs),
77 lifetimes: LifetimeEnv::from_struct_item(strct, &[]),
78 methods: vec![],
79 mutability,
80 attrs,
81 }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use insta::{self, Settings};
88
89 use syn;
90
91 use super::Struct;
92
93 #[test]
94 fn simple_struct() {
95 let mut settings = Settings::new();
96 settings.set_sort_maps(true);
97
98 settings.bind(|| {
99 insta::assert_yaml_snapshot!(Struct::new(
100 &syn::parse_quote! {
101 #[diplomat::rust_link(foo::Bar, Struct)]
103 struct MyLocalStruct {
104 a: i32,
105 b: Box<MyLocalStruct>
106 }
107 },
108 true,
109 &Default::default()
110 ));
111 });
112 }
113}