bevy_save/
middleware.rs

1//! Middleware for [`Format`](crate::prelude::Format), allowing you to easily add features like compression or encryption.
2
3#[cfg(feature = "brotli")]
4mod brotli {
5    use std::marker::PhantomData;
6
7    use brotli::enc::BrotliEncoderParams;
8
9    use crate::prelude::*;
10
11    /// Brotli middleware for compressing your data after serializing
12    ///
13    /// # Example
14    /// ```rust
15    /// # use bevy_save::prelude::*;
16    /// struct MyPipeline;
17    ///
18    /// impl Pipeline for MyPipeline {
19    ///     type Backend = DefaultBackend;
20    ///     /// This will emit brotli-compressed MessagePack
21    ///     type Format = Brotli<DefaultFormat>;
22    ///     type Key<'a> = &'a str;
23    ///
24    ///     fn key(&self) -> Self::Key<'_> {
25    ///         "my_pipeline"
26    ///     }
27    /// }
28    pub struct Brotli<F>(PhantomData<F>);
29
30    impl<F> Default for Brotli<F> {
31        fn default() -> Self {
32            Self(PhantomData)
33        }
34    }
35
36    impl<F: Format> Format for Brotli<F> {
37        fn extension() -> &'static str {
38            // TODO: Should be `format!("{}.br", F::extension())`
39            ".br"
40        }
41
42        fn serialize<W: std::io::prelude::Write, T: serde::Serialize>(
43            writer: W,
44            value: &T,
45        ) -> Result<(), crate::Error> {
46            let params = BrotliEncoderParams::default();
47            let writer = brotli::CompressorWriter::with_params(writer, 4096, &params);
48            F::serialize(writer, value)
49        }
50
51        fn deserialize<
52            R: std::io::prelude::Read,
53            S: for<'de> serde::de::DeserializeSeed<'de, Value = T>,
54            T,
55        >(
56            reader: R,
57            seed: S,
58        ) -> Result<T, crate::Error> {
59            let reader = brotli::Decompressor::new(reader, 4096);
60            F::deserialize(reader, seed)
61        }
62    }
63}
64
65#[cfg(feature = "brotli")]
66pub use brotli::Brotli;