s2n_tls/connection/
builder.rs1use crate::{
5 config::Config,
6 connection::Connection,
7 enums::Mode,
8 error::Error,
9 pool::{Pool, PooledConnection},
10};
11
12pub trait Builder: Clone {
14 type Output: AsMut<Connection> + AsRef<Connection>;
15 fn build_connection(&self, mode: Mode) -> Result<Self::Output, Error>;
16}
17
18impl Builder for Config {
20 type Output = Connection;
21 fn build_connection(&self, mode: Mode) -> Result<Self::Output, Error> {
22 let mut conn = Connection::new(mode);
23 conn.set_config(self.clone())?;
24 Ok(conn)
25 }
26}
27
28impl<T: Pool + Clone> Builder for T {
30 type Output = PooledConnection<T>;
31 fn build_connection(&self, mode: Mode) -> Result<Self::Output, Error> {
32 if mode == self.mode() {
33 Ok(PooledConnection::new(self)?)
34 } else {
35 Err(Error::INVALID_INPUT)
36 }
37 }
38}
39
40#[derive(Clone)]
45pub struct ModifiedBuilder<F, B: Builder>
46where
47 F: Fn(&mut Connection) -> Result<&mut Connection, Error> + Clone,
48{
49 builder: B,
50 modifier: F,
51}
52
53impl<F, B: Builder> ModifiedBuilder<F, B>
54where
55 F: Fn(&mut Connection) -> Result<&mut Connection, Error> + Clone,
56{
57 pub fn new(builder: B, modifier: F) -> Self {
58 Self { builder, modifier }
59 }
60}
61
62impl<F, B: Builder> Builder for ModifiedBuilder<F, B>
63where
64 F: Fn(&mut Connection) -> Result<&mut Connection, Error> + Clone,
65{
66 type Output = B::Output;
67 fn build_connection(&self, mode: Mode) -> Result<Self::Output, Error> {
68 let mut conn = self.builder.build_connection(mode)?;
69 (self.modifier)(conn.as_mut())?;
70 Ok(conn)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use crate::pool::ConfigPoolBuilder;
78
79 #[test]
80 fn config_builder() -> Result<(), Box<dyn std::error::Error>> {
81 let config = Config::default();
82 let conn = config.build_connection(Mode::Server)?;
83 assert_eq!(conn.config(), Some(config));
84 Ok(())
85 }
86
87 #[test]
88 fn pool_builder() -> Result<(), Box<dyn std::error::Error>> {
89 let config = Config::default();
90 let pool = ConfigPoolBuilder::new(Mode::Server, config.clone()).build();
91 let conn = pool.build_connection(Mode::Server)?;
92 assert_eq!(conn.as_ref().config(), Some(config));
93 Ok(())
94 }
95
96 #[test]
97 fn modified_builder() -> Result<(), Box<dyn std::error::Error>> {
98 let config_a = Config::default();
99 let config_b = Config::default();
100 assert!(config_a != config_b);
101
102 let builder =
103 ModifiedBuilder::new(config_a.clone(), |conn| conn.set_config(config_b.clone()));
104
105 let conn = builder.build_connection(Mode::Server)?;
106 assert!(conn.config() != Some(config_a));
107 assert_eq!(conn.config(), Some(config_b));
108 Ok(())
109 }
110}