1#![cfg_attr(docsrs, feature(doc_cfg))]
4#![cfg_attr(not(feature = "std"), no_std)]
5
6use core::{marker::PhantomData, mem::MaybeUninit};
7
8use wincode::{
9 error::{ReadResult, WriteError, WriteResult},
10 io::{Reader, Writer},
11};
12
13#[cfg(feature = "alloc")]
14extern crate alloc;
15
16mod de;
17mod ser;
18
19pub use {de::Deserializer, ser::Serializer};
20
21#[repr(transparent)]
25pub struct SerdeCompat<T> {
26 _marker: PhantomData<T>,
27}
28
29unsafe impl<'de, C, T> wincode::SchemaRead<'de, C> for SerdeCompat<T>
30where
31 C: wincode::config::Config,
32 T: serde::Deserialize<'de>,
33{
34 type Dst = T;
35
36 fn read(
37 reader: impl Reader<'de>,
38 dst: &mut MaybeUninit<Self::Dst>,
39 ) -> ReadResult<()> {
40 let deserializer = Deserializer::<_, C>::new(reader);
41 let value = T::deserialize(deserializer)?;
42 dst.write(value);
43 Ok(())
44 }
45}
46
47unsafe impl<C, T> wincode::SchemaWrite<C> for SerdeCompat<T>
48where
49 C: wincode::config::Config,
50 T: serde::Serialize,
51{
52 type Src = T;
53
54 fn size_of(src: &Self::Src) -> WriteResult<usize> {
55 let mut serializer = ser::SizeOf::<C>::new();
56 serializer = src.serialize(serializer)?;
57 Ok(serializer.serialized_size())
58 }
59
60 fn write(writer: impl Writer, src: &Self::Src) -> WriteResult<()> {
61 let serializer = Serializer::<_, C>::new(writer);
62 src.serialize(serializer).map_err(WriteError::from)
63 }
64}
65
66#[cfg(all(feature = "alloc", test))]
67mod tests {
68 use serde::{Deserialize, Serialize};
69
70 use super::SerdeCompat;
71
72 #[test]
73 fn test_flattened_roundtrip()
74 -> Result<(), alloc::boxed::Box<dyn core::error::Error>> {
75 #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
76 struct InnerMost<'a> {
77 #[serde(borrow)]
78 msg: &'a str,
79 #[serde(borrow)]
80 bytes: &'a [u8],
81 }
82 #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
83 struct InnerMore<'a> {
84 u32_value: u32,
85 #[serde(borrow)]
86 inner: InnerMost<'a>,
87 }
88 #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
89 struct Outer<'a> {
90 #[serde(borrow)]
91 inner: InnerMore<'a>,
92 bool_value: bool,
93 }
94
95 let value = Outer {
96 inner: InnerMore {
97 u32_value: 69_420,
98 inner: InnerMost {
99 msg: "test msg",
100 bytes: b"test bytes",
101 },
102 },
103 bool_value: true,
104 };
105 let value_serialized_bincode = bincode::serialize(&value)?;
106 let value_serialized_wincode =
107 <SerdeCompat<Outer> as wincode::Serialize>::serialize(&value)?;
108 assert_eq!(value_serialized_bincode, value_serialized_wincode);
109 let value_deserialized =
110 <SerdeCompat<Outer> as wincode::Deserialize>::deserialize(
111 &value_serialized_wincode,
112 )?;
113 assert_eq!(value_deserialized, value);
114 Ok(())
115 }
116}