1
use anyhow::Result;
2

            
3
use crate::RwBuilder;
4
use wincode::io::{ std_read::ReadAdapter, std_write::WriteAdapter, Writer };
5

            
6
/// Type returned by the `wincode` function on the `RwBuilder` trait.
7
/// It is itself not an `RwBuilder` so can't be chained further.
8
/// This is why we call it a sink.
9
///
10
/// Note: This builder provides `load` and `save` methods for serialization.
11
/// Due to wincode's schema trait requirements, types must implement both
12
/// `serde` traits and `wincode`'s `SchemaRead`/`SchemaWrite` traits.
13
#[derive(Debug)]
14
pub struct Builder<B> where B: RwBuilder {
15
    /// The inner builder it wraps
16
    builder: B,
17
}
18

            
19
impl<B> Builder<B> where B: RwBuilder {
20
    /// Factory function to wrap an inner builder
21
    #[must_use]
22
1
    pub const fn new(builder: B) -> Self {
23
1
        Self { builder }
24
1
    }
25

            
26
    /// Load a value from the builder
27
    ///
28
    /// # Errors
29
    /// Returns an error if deserialization or reading fails
30
1
    pub fn load<T>(&self) -> Result<T>
31
1
        where
32
1
            T: for<'de> serde::de::Deserialize<'de> +
33
1
                for<'de> wincode::SchemaRead<'de, wincode::config::DefaultConfig, Dst = T>
34
    {
35
1
        let reader = self.builder.reader()?;
36
1
        let adapter = ReadAdapter::new(reader);
37
1
        let result = wincode::deserialize_from(adapter)?;
38
1
        Ok(result)
39
1
    }
40

            
41
    /// Save a value to the builder
42
    ///
43
    /// # Errors
44
    /// Returns an error if serialization or writing fails
45
1
    pub fn save<T>(&self, value: &T) -> Result<()>
46
1
        where
47
1
            T: serde::ser::Serialize +
48
1
                wincode::SchemaWrite<wincode::config::DefaultConfig, Src = T> +
49
1
                ?Sized
50
    {
51
1
        let writer = self.builder.writer()?;
52
1
        let mut adapter = WriteAdapter::new(writer);
53
1
        wincode::serialize_into(&mut adapter, value)?;
54
1
        adapter.finish()?;
55
1
        Ok(())
56
1
    }
57
}