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                #[allow(unused_mut)]
33                let mut middleware = ::std::collections::VecDeque::new();
34
35                $( middleware.push_front(&mut self.$mw_name as &mut dyn $crate::wire::Middleware); )*
36
37                middleware
38            }
39        }
40
41        impl $crate::wire::middleware::Pipeline for $ty
42        {
43            fn encode_data(&mut self, mut data: Vec<u8>)
44                -> Result<Vec<u8>, $crate::Error> {
45                use $crate::wire::Middleware;
46
47                $( data = self.$mw_name.encode_data(data)?; )*
48
49                Ok(data)
50            }
51
52            fn decode_data(&mut self, mut data: Vec<u8>)
53                -> Result<Vec<u8>, $crate::Error> {
54                for middleware in self.middleware_mut() {
55                    data = middleware.decode_data(data)?;
56                }
57
58                Ok(data)
59            }
60        }
61    };
62}
63
64// The default middleware pipeline.
65#[cfg(feature = "middleware-compression")]
66define_middleware_pipeline!(Default {
67    compression: middleware::compression::Compression
68});
69
70// The default middleware pipeline.
71#[cfg(not(feature = "middleware-compression"))]
72define_middleware_pipeline!(Default {
73});
74
75impl std::default::Default for Default
76{
77    fn default() -> Self {
78        Default {
79            // The default middleware pipeline.
80            #[cfg(feature = "middleware-compression")]
81            compression: middleware::compression::Compression::Disabled,
82        }
83    }
84}
85
86#[cfg(test)]
87mod test
88{
89    use crate::{wire, wire::middleware::Pipeline, Error};
90
91    define_middleware_pipeline!(NullPipeline {
92        encryption: NullMiddleware,
93        compression: NullMiddleware
94    });
95
96    #[derive(Clone, Debug)]
97    pub struct NullMiddleware;
98
99    impl wire::Middleware for NullMiddleware
100    {
101        fn encode_data(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error> { Ok(data) }
102        fn decode_data(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error> { Ok(data) }
103    }
104
105    #[test]
106    fn successfully_passes_data_through_the_pipeline() {
107        let mut null_pipeline = NullPipeline {
108            encryption: NullMiddleware,
109            compression: NullMiddleware,
110        };
111
112        let data = vec![7, 2, 5, 5, 1, 2, 3, 4, 2, 4, 8];
113
114        assert_eq!(null_pipeline.encode_data(data.clone()).unwrap(), data.clone());
115        assert_eq!(null_pipeline.decode_data(data.clone()).unwrap(), data.clone());
116    }
117}
118