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, ¶ms);
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;