1use serde_core::ser::{self, Serialize, SerializeTupleStruct, Serializer};
2use std::cell::RefCell;
3use std::rc::Rc;
4use std::sync::{Arc, Mutex};
5
6#[cfg(feature = "comments")]
7use crate::Commented;
8use crate::{
9 ArcAnchor, ArcRecursion, ArcRecursive, ArcWeakAnchor, DoubleQuoted, FlowMap, FlowSeq,
10 NullableTilde, RcAnchor, RcRecursion, RcRecursive, RcWeakAnchor, SingleQuoted, SpaceAfter,
11 Tagged,
12};
13
14#[cfg(feature = "comments")]
15use super::NAME_TUPLE_COMMENTED;
16use super::{
17 NAME_DOUBLE_QUOTED, NAME_FLOW_MAP, NAME_FLOW_SEQ, NAME_NULLABLE_TILDE, NAME_SINGLE_QUOTED,
18 NAME_SPACE_AFTER, NAME_TUPLE_ANCHOR, NAME_TUPLE_TAGGED, NAME_TUPLE_WEAK,
19};
20
21struct RcRecursivePayload<'a, T>(&'a Rc<RefCell<Option<T>>>);
28struct ArcRecursivePayload<'a, T>(&'a Arc<Mutex<Option<T>>>);
29
30impl<T: Serialize> Serialize for RcRecursivePayload<'_, T> {
31 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
32 let borrowed = self.0.borrow();
33 if let Some(value) = borrowed.as_ref() {
34 value.serialize(s)
35 } else {
36 s.serialize_unit()
37 }
38 }
39}
40
41impl<T: Serialize> Serialize for ArcRecursivePayload<'_, T> {
42 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
43 let guard = self
44 .0
45 .lock()
46 .map_err(|_| ser::Error::custom("recursive Arc anchor mutex poisoned"))?;
47 if let Some(value) = guard.as_ref() {
48 value.serialize(s)
49 } else {
50 s.serialize_unit()
51 }
52 }
53}
54
55impl<T: Serialize> Serialize for RcAnchor<T> {
57 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
58 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_ANCHOR, 2)?;
60 let ptr = Rc::as_ptr(&self.0) as usize;
61 ts.serialize_field(&ptr)?;
62 ts.serialize_field(&*self.0)?;
63 ts.end()
64 }
65}
66impl<T: Serialize> Serialize for ArcAnchor<T> {
67 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
68 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_ANCHOR, 2)?;
69 let ptr = Arc::as_ptr(&self.0) as usize;
70 ts.serialize_field(&ptr)?;
71 ts.serialize_field(&*self.0)?;
72 ts.end()
73 }
74}
75impl<T: Serialize> Serialize for RcRecursive<T> {
76 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
77 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_ANCHOR, 2)?;
78 let ptr = Rc::as_ptr(&self.0) as usize;
79 ts.serialize_field(&ptr)?;
80 let borrowed = self.0.borrow();
81 let value = borrowed
82 .as_ref()
83 .ok_or_else(|| ser::Error::custom("recursive Rc anchor not initialized"))?;
84 ts.serialize_field(value)?;
85 ts.end()
86 }
87}
88impl<T: Serialize> Serialize for ArcRecursive<T> {
89 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
90 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_ANCHOR, 2)?;
91 let ptr = Arc::as_ptr(&self.0) as usize;
92 ts.serialize_field(&ptr)?;
93 let guard = self
94 .0
95 .lock()
96 .map_err(|_| ser::Error::custom("recursive Arc anchor mutex poisoned"))?;
97 let value = guard
98 .as_ref()
99 .ok_or_else(|| ser::Error::custom("recursive Arc anchor not initialized"))?;
100 ts.serialize_field(value)?;
101 ts.end()
102 }
103}
104impl<T: Serialize> Serialize for RcWeakAnchor<T> {
105 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
106 let up = self.0.upgrade();
107 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_WEAK, 3)?;
108 let ptr = self.0.as_ptr() as usize;
109 ts.serialize_field(&ptr)?;
110 ts.serialize_field(&up.is_some())?;
111 if let Some(rc) = up {
112 ts.serialize_field(&*rc)?;
113 } else {
114 ts.serialize_field(&())?; }
116 ts.end()
117 }
118}
119impl<T: Serialize> Serialize for ArcWeakAnchor<T> {
120 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
121 let up = self.0.upgrade();
122 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_WEAK, 3)?;
123 let ptr = self.0.as_ptr() as usize;
124 ts.serialize_field(&ptr)?;
125 ts.serialize_field(&up.is_some())?;
126 if let Some(arc) = up {
127 ts.serialize_field(&*arc)?;
128 } else {
129 ts.serialize_field(&())?;
130 }
131 ts.end()
132 }
133}
134impl<T: Serialize> Serialize for RcRecursion<T> {
135 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
136 let up = self.0.upgrade();
137 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_WEAK, 3)?;
138 let ptr = self.0.as_ptr() as usize;
139 ts.serialize_field(&ptr)?;
140 ts.serialize_field(&up.is_some())?;
141 if let Some(rc) = up {
142 ts.serialize_field(&RcRecursivePayload(&rc))?;
143 } else {
144 ts.serialize_field(&())?;
145 }
146 ts.end()
147 }
148}
149impl<T: Serialize> Serialize for ArcRecursion<T> {
150 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
151 let up = self.0.upgrade();
152 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_WEAK, 3)?;
153 let ptr = self.0.as_ptr() as usize;
154 ts.serialize_field(&ptr)?;
155 ts.serialize_field(&up.is_some())?;
156 if let Some(arc) = up {
157 ts.serialize_field(&ArcRecursivePayload(&arc))?;
158 } else {
159 ts.serialize_field(&())?;
160 }
161 ts.end()
162 }
163}
164
165impl<T: Serialize> Serialize for FlowSeq<T> {
167 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
168 s.serialize_newtype_struct(NAME_FLOW_SEQ, &self.0)
169 }
170}
171impl<T: Serialize> Serialize for FlowMap<T> {
172 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
173 s.serialize_newtype_struct(NAME_FLOW_MAP, &self.0)
174 }
175}
176impl<T: Serialize> Serialize for SpaceAfter<T> {
177 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
178 s.serialize_newtype_struct(NAME_SPACE_AFTER, &self.0)
179 }
180}
181impl<T: AsRef<str>> Serialize for DoubleQuoted<T> {
182 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
183 s.serialize_newtype_struct(NAME_DOUBLE_QUOTED, self.0.as_ref())
184 }
185}
186impl<T: AsRef<str>> Serialize for SingleQuoted<T> {
187 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
188 s.serialize_newtype_struct(NAME_SINGLE_QUOTED, self.0.as_ref())
189 }
190}
191impl<T: Serialize> Serialize for NullableTilde<T> {
192 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
193 if !s.is_human_readable() {
194 return self.0.serialize(s);
195 }
196
197 match &self.0 {
198 Some(value) => s.serialize_some(value),
199 None => s.serialize_newtype_struct(NAME_NULLABLE_TILDE, &self.0),
200 }
201 }
202}
203
204#[cfg(feature = "comments")]
205impl<T: Serialize> Serialize for Commented<T> {
206 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
207 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_COMMENTED, 2)?;
210 ts.serialize_field(&self.1)?; ts.serialize_field(&self.0)?; ts.end()
213 }
214}
215
216impl<T: Serialize> Serialize for Tagged<T> {
217 fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
218 let Some(tag) = self.1.as_ref() else {
219 return self.0.serialize(s);
222 };
223
224 let mut ts = s.serialize_tuple_struct(NAME_TUPLE_TAGGED, 2)?;
227 ts.serialize_field(tag)?;
228 ts.serialize_field(&self.0)?;
229 ts.end()
230 }
231}