serdapt/
cell.rs

1// Copyright (c) 2024 Stephane Raux. Distributed under the 0BSD license.
2
3use crate::{DeserializeWith, SerializeWith};
4use core::{cell::RefCell, marker::PhantomData};
5use serde::{ser::Error, Deserializer, Serializer};
6
7/// Adapter for cell-like types
8///
9/// # Example
10/// ```
11/// use serde::{Deserialize, Serialize};
12/// use serde_json::json;
13/// use std::cell::Cell;
14///
15/// #[derive(Deserialize, Serialize)]
16/// struct IntCell(#[serde(with = "serdapt::Cell::<serdapt::Str>")] Cell<i32>);
17///
18/// let v = serde_json::to_value(IntCell(Cell::new(33))).unwrap();
19/// assert_eq!(v, json!("33"));
20/// ```
21pub struct Cell<F>(PhantomData<F>);
22
23impl<F> Cell<F> {
24    /// Serializes value with adapter
25    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    /// Deserializes value with adapter
35    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}