1use crate::{DeserializeWith, SerializeWith};
4use core::{cell::RefCell, marker::PhantomData};
5use serde::{ser::Error, Deserializer, Serializer};
6
7pub struct Cell<F>(PhantomData<F>);
22
23impl<F> Cell<F> {
24 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
26 where
27 T: ?Sized,
28 S: Serializer,
29 Self: SerializeWith<T>,
30 {
31 Self::serialize_with(value, serializer)
32 }
33
34 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
36 where
37 D: Deserializer<'de>,
38 Self: DeserializeWith<'de, T>,
39 {
40 Self::deserialize_with(deserializer)
41 }
42}
43
44impl<F, T> SerializeWith<core::cell::Cell<T>> for Cell<F>
45where
46 F: SerializeWith<T>,
47 T: Copy,
48{
49 fn serialize_with<S: Serializer>(
50 value: &core::cell::Cell<T>,
51 serializer: S,
52 ) -> Result<S::Ok, S::Error> {
53 F::serialize_with(&value.get(), serializer)
54 }
55}
56
57impl<'de, F, T> DeserializeWith<'de, core::cell::Cell<T>> for Cell<F>
58where
59 F: DeserializeWith<'de, T>,
60{
61 fn deserialize_with<D>(deserializer: D) -> Result<core::cell::Cell<T>, D::Error>
62 where
63 D: Deserializer<'de>,
64 {
65 F::deserialize_with(deserializer).map(Into::into)
66 }
67}
68
69impl<F, T> SerializeWith<RefCell<T>> for Cell<F>
70where
71 F: SerializeWith<T>,
72 T: ?Sized,
73{
74 fn serialize_with<S: Serializer>(value: &RefCell<T>, serializer: S) -> Result<S::Ok, S::Error> {
75 F::serialize_with(&*value.try_borrow().map_err(S::Error::custom)?, serializer)
76 }
77}
78
79impl<'de, F, T> DeserializeWith<'de, RefCell<T>> for Cell<F>
80where
81 F: DeserializeWith<'de, T>,
82{
83 fn deserialize_with<D>(deserializer: D) -> Result<RefCell<T>, D::Error>
84 where
85 D: Deserializer<'de>,
86 {
87 F::deserialize_with(deserializer).map(Into::into)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use crate::test_utils::check_serialization;
94 use core::cell::{Cell, RefCell};
95 use serde::{Deserialize, Serialize};
96 use serde_json::json;
97
98 #[derive(Debug, Deserialize, PartialEq, Serialize)]
99 struct CellWrapper(#[serde(with = "crate::Cell::<crate::Str>")] Cell<i32>);
100
101 #[test]
102 fn adapted_cell_roundtrips() {
103 check_serialization(CellWrapper(3.into()), json!("3"));
104 }
105
106 #[derive(Debug, Deserialize, PartialEq, Serialize)]
107 struct RefCellWrapper(#[serde(with = "crate::Cell::<crate::Str>")] RefCell<i32>);
108
109 #[test]
110 fn adapted_ref_cell_roundtrips() {
111 check_serialization(RefCellWrapper(3.into()), json!("3"));
112 }
113
114 #[test]
115 fn serializing_mutably_borrowed_ref_cell_returns_error() {
116 let cell = RefCellWrapper(3.into());
117 let mut m = cell.0.borrow_mut();
118 serde_json::to_string(&cell).unwrap_err();
119 *m = 4;
120 }
121}