djin_protocol/wire/middleware/
pipeline.rs

1//! An ordered list of middleware that performs tested transformations.
2
3use crate::{wire::middleware, Error};
4use std;
5
6/// A middleware pipeline.
7pub trait Pipeline : std::fmt::Debug
8{
9    fn encode_data(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error>;
10    fn decode_data(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error>;
11}
12
13/// Creates an instance of the default middleware.
14pub fn default() -> Default {
15    Default::default()
16}
17
18/// Defines a new middleware pipeline that implements `Pipeline`.
19#[macro_export]
20macro_rules! define_middleware_pipeline {
21    ($ty:ident { $( $mw_name:ident : $mw_ty:ty ),+ } ) => {
22        #[derive(Clone, Debug)]
23        pub struct $ty
24        {
25            $( pub $mw_name : $mw_ty),+
26        }
27
28        impl $ty
29        {
30            /// Gets the middleware pipeline.
31            pub fn middleware_mut(&mut self) -> ::std::collections::VecDeque<&mut dyn $crate::wire::Middleware> {
32                let mut middleware = ::std::collections::VecDeque::new();
33
34                $( middleware.push_front(&mut self.$mw_name as &mut dyn $crate::wire::Middleware); )+
35
36                middleware
37            }
38        }
39
40        impl $crate::wire::middleware::Pipeline for $ty
41        {
42            fn encode_data(&mut self, mut data: Vec<u8>)
43                -> Result<Vec<u8>, $crate::Error> {
44                use $crate::wire::Middleware;
45
46                $( data = self.$mw_name.encode_data(data)?; )+
47
48                Ok(data)
49            }
50
51            fn decode_data(&mut self, mut data: Vec<u8>)
52                -> Result<Vec<u8>, $crate::Error> {
53                for middleware in self.middleware_mut() {
54                    data = middleware.decode_data(data)?;
55                }
56
57                Ok(data)
58            }
59        }
60    }
61}
62
63// The default middleware pipeline.
64define_middleware_pipeline!(Default {
65    compression: middleware::compression::Compression
66});
67
68impl std::default::Default for Default
69{
70    fn default() -> Self {
71        Default {
72            compression: middleware::compression::Compression::Disabled,
73        }
74    }
75}
76
77#[cfg(test)]
78mod test
79{
80    use crate::{wire, wire::middleware::Pipeline, Error};
81
82    define_middleware_pipeline!(NullPipeline {
83        encryption: NullMiddleware,
84        compression: NullMiddleware
85    });
86
87    #[derive(Clone, Debug)]
88    pub struct NullMiddleware;
89
90    impl wire::Middleware for NullMiddleware
91    {
92        fn encode_data(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error> { Ok(data) }
93        fn decode_data(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error> { Ok(data) }
94    }
95
96    #[test]
97    fn successfully_passes_data_through_the_pipeline() {
98        let mut null_pipeline = NullPipeline {
99            encryption: NullMiddleware,
100            compression: NullMiddleware,
101        };
102
103        let data = vec![7, 2, 5, 5, 1, 2, 3, 4, 2, 4, 8];
104
105        assert_eq!(null_pipeline.encode_data(data.clone()).unwrap(), data.clone());
106        assert_eq!(null_pipeline.decode_data(data.clone()).unwrap(), data.clone());
107    }
108}
109