conjure_cp_core/ast/
serde.rs1use std::cell::RefCell;
7use std::fmt::Display;
8use std::rc::Rc;
9
10use serde::Deserialize;
11use serde::Serialize;
12use serde::de::Error;
13use serde_with::{DeserializeAs, SerializeAs};
14use ustr::Ustr;
15
16#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, Hash)]
20pub struct ObjId {
21 pub type_name: Ustr,
23
24 pub object_id: u32,
26}
27
28impl Display for ObjId {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 write!(f, "obj_id_{}_{}", self.type_name, self.object_id)
31 }
32}
33
34pub trait HasId {
38 const TYPE_NAME: &'static str;
39
40 fn id(&self) -> ObjId;
42}
43
44pub trait DefaultWithId: HasId {
46 fn default_with_id(id: ObjId) -> Self;
48}
49
50pub struct RcRefCellAsId;
60
61impl<T> SerializeAs<Rc<RefCell<T>>> for RcRefCellAsId
64where
65 T: HasId,
66{
67 fn serialize_as<S>(source: &Rc<RefCell<T>>, serializer: S) -> Result<S::Ok, S::Error>
68 where
69 S: serde::Serializer,
70 {
71 let id = (**source).borrow().id();
72 id.serialize(serializer)
73 }
74}
75
76impl<'de, T> DeserializeAs<'de, Rc<RefCell<T>>> for RcRefCellAsId
78where
79 T: HasId + DefaultWithId,
80{
81 fn deserialize_as<D>(deserializer: D) -> Result<Rc<RefCell<T>>, D::Error>
82 where
83 D: serde::Deserializer<'de>,
84 {
85 let id = ObjId::deserialize(deserializer).map_err(Error::custom)?;
86 assert_eq!(id.type_name.as_str(), T::TYPE_NAME);
87 Ok(Rc::new(RefCell::new(T::default_with_id(id))))
88 }
89}
90
91pub struct RcRefCellAsInner;
99
100impl<T> SerializeAs<Rc<RefCell<T>>> for RcRefCellAsInner
101where
102 T: Serialize + HasId,
103{
104 fn serialize_as<S>(source: &Rc<RefCell<T>>, serializer: S) -> Result<S::Ok, S::Error>
105 where
106 S: serde::Serializer,
107 {
108 (**source).borrow().serialize(serializer)
109 }
110}
111
112impl<T> SerializeAs<Rc<T>> for RcRefCellAsInner
113where
114 T: Serialize + HasId,
115{
116 fn serialize_as<S>(source: &Rc<T>, serializer: S) -> Result<S::Ok, S::Error>
117 where
118 S: serde::Serializer,
119 {
120 source.serialize(serializer)
121 }
122}
123
124impl<'de, T> DeserializeAs<'de, Rc<RefCell<T>>> for RcRefCellAsInner
125where
126 T: Deserialize<'de> + HasId + DefaultWithId,
127{
128 fn deserialize_as<D>(deserializer: D) -> Result<Rc<RefCell<T>>, D::Error>
129 where
130 D: serde::Deserializer<'de>,
131 {
132 let val = T::deserialize(deserializer)?;
133 Ok(Rc::new(RefCell::new(val)))
134 }
135}
136
137impl<'de, T> DeserializeAs<'de, Rc<T>> for RcRefCellAsInner
138where
139 T: Deserialize<'de> + HasId + DefaultWithId,
140{
141 fn deserialize_as<D>(deserializer: D) -> Result<Rc<T>, D::Error>
142 where
143 D: serde::Deserializer<'de>,
144 {
145 let val = T::deserialize(deserializer)?;
146 Ok(Rc::new(val))
147 }
148}