Skip to main content

pilota_build/plugin/
serde.rs

1use crate::tags::SerdeAttribute;
2
3#[derive(Clone, Copy)]
4pub struct SerdePlugin;
5
6impl crate::Plugin for SerdePlugin {
7    fn on_item(
8        &mut self,
9        cx: &crate::Context,
10        def_id: crate::DefId,
11        item: std::sync::Arc<crate::rir::Item>,
12    ) {
13        let attribute = cx
14            .node_tags(def_id)
15            .and_then(|tags| tags.get::<SerdeAttribute>().cloned());
16
17        match &*item {
18            crate::rir::Item::Message(_)
19            | crate::rir::Item::Enum(_)
20            | crate::rir::Item::NewType(_) => {
21                cx.with_adjust_mut(def_id, |adj| {
22                    adj.add_attrs(&[
23                        "#[derive(::pilota::serde::Serialize, ::pilota::serde::Deserialize)]"
24                            .into(),
25                    ]);
26                    if let Some(attribute) = attribute {
27                        let attr = attribute.0.to_string().replace('\\', "");
28                        adj.add_attrs(&[attr.into()]);
29                    }
30                });
31            }
32            _ => {}
33        };
34
35        if let crate::rir::Item::Enum(e) = &*item {
36            if e.repr.is_some() {
37                cx.with_adjust_mut(def_id, |adj| {
38                    adj.add_attrs(&["#[serde(transparent)]".into()]);
39                })
40            }
41        }
42
43        crate::plugin::walk_item(self, cx, def_id, item)
44    }
45
46    fn on_field(
47        &mut self,
48        cx: &crate::Context,
49        def_id: crate::DefId,
50        f: std::sync::Arc<crate::rir::Field>,
51    ) {
52        if let Some(attribute) = cx
53            .tags(f.tags_id)
54            .and_then(|tags| tags.get::<SerdeAttribute>().cloned())
55        {
56            let attr = attribute.0.replace('\\', "");
57            cx.with_adjust_mut(def_id, |adj| adj.add_attrs(&[attr.into()]))
58        }
59    }
60
61    fn on_variant(
62        &mut self,
63        cx: &crate::Context,
64        def_id: crate::DefId,
65        variant: std::sync::Arc<crate::rir::EnumVariant>,
66    ) {
67        if let Some(attribute) = cx
68            .node_tags(variant.did)
69            .and_then(|tags| tags.get::<SerdeAttribute>().cloned())
70        {
71            let attr = attribute.0.replace('\\', "");
72            cx.with_adjust_mut(def_id, |adj| adj.add_attrs(&[attr.into()]))
73        }
74    }
75}