pass_it_on/
configuration.rs1#[cfg(all(feature = "parse-cfg", feature = "client"))]
2pub mod client_configuration_file;
3#[cfg(all(feature = "parse-cfg", feature = "server"))]
4pub mod server_configuration_file;
5
6#[cfg(feature = "server")]
7use crate::endpoints::{Endpoint, EndpointChannel, EndpointConfig};
8use crate::interfaces::{Interface, InterfaceConfig};
9use crate::notifications::Key;
10use crate::Error;
11
12#[cfg(feature = "server")]
13#[derive(Debug)]
15pub struct ServerConfiguration {
16 key: Key,
17 interfaces: Vec<Box<dyn Interface + Send>>,
18 endpoints: Vec<Box<dyn Endpoint + Send>>,
19}
20
21#[cfg(feature = "server")]
22impl ServerConfiguration {
23 pub fn new<S: AsRef<str>>(
25 key: S,
26 interfaces: Vec<Box<dyn Interface + Send>>,
27 endpoints: Vec<Box<dyn Endpoint + Send>>,
28 ) -> Result<Self, Error> {
29 let key = Key::derive_shared_key(key);
30 let config = Self { key, interfaces, endpoints };
31 Self::validate(config)
32 }
33
34 pub(crate) fn endpoint_channels(&self) -> Vec<EndpointChannel> {
35 use crate::notifications::ValidatedNotification;
36 use crate::CHANNEL_BUFFER;
37 use tokio::sync::broadcast;
38 use tokio::sync::broadcast::{Receiver, Sender};
39
40 let mut endpoints = Vec::new();
41 for endpoint in &self.endpoints {
42 let (endpoint_tx, _endpoint_rx): (Sender<ValidatedNotification>, Receiver<ValidatedNotification>) =
43 broadcast::channel(CHANNEL_BUFFER);
44 let keys = endpoint.generate_keys(&self.key);
45 endpoints.push(EndpointChannel::from(endpoint.clone(), endpoint_tx, keys));
46 }
47 endpoints
48 }
49
50 pub fn key(&self) -> &Key {
52 &self.key
53 }
54
55 pub fn interfaces(&self) -> Vec<Box<dyn Interface + Send>> {
57 self.interfaces.clone()
58 }
59
60 pub fn endpoints(&self) -> &[Box<dyn Endpoint + Send>] {
62 &self.endpoints
63 }
64
65 fn validate(config: ServerConfiguration) -> Result<ServerConfiguration, Error> {
66 if config.interfaces.is_empty() {
67 return Err(Error::MissingInterface);
68 }
69
70 if config.endpoints.is_empty() {
71 return Err(Error::MissingEndpoint);
72 }
73
74 Ok(config)
75 }
76}
77
78#[cfg(all(feature = "parse-cfg", feature = "server"))]
79impl TryFrom<&str> for ServerConfiguration {
80 type Error = Error;
81
82 fn try_from(value: &str) -> Result<Self, Self::Error> {
83 server_configuration_file::ServerConfigFileParser::from(value)
84 }
85}
86
87#[cfg(feature = "client")]
88#[derive(Debug)]
90pub struct ClientConfiguration {
91 key: Key,
92 interfaces: Vec<Box<dyn Interface + Send>>,
93}
94
95#[cfg(feature = "client")]
96impl ClientConfiguration {
97 pub fn new<S: AsRef<str>>(key: S, interfaces: Vec<Box<dyn Interface + Send>>) -> Result<Self, Error> {
99 let key = Key::derive_shared_key(key);
100 let config = Self { key, interfaces };
101 Self::validate(config)
102 }
103
104 pub fn key(&self) -> &Key {
106 &self.key
107 }
108
109 pub fn interfaces(&self) -> Vec<Box<dyn Interface + Send>> {
111 self.interfaces.clone()
112 }
113
114 fn validate(config: ClientConfiguration) -> Result<ClientConfiguration, Error> {
115 if config.interfaces.is_empty() {
116 return Err(Error::MissingInterface);
117 }
118 Ok(config)
119 }
120}
121
122#[cfg(all(feature = "parse-cfg", feature = "client"))]
123impl TryFrom<&str> for ClientConfiguration {
124 type Error = Error;
125
126 fn try_from(value: &str) -> Result<Self, Self::Error> {
127 client_configuration_file::ClientConfigFileParser::from(value)
128 }
129}
130
131#[cfg(all(feature = "parse-cfg", any(feature = "client", feature = "server")))]
132fn collect_interfaces(
133 interface_configs: Vec<Box<dyn InterfaceConfig>>,
134) -> Result<Vec<Box<dyn Interface + Send>>, Error> {
135 interface_configs.iter().map(|cfg| cfg.to_interface()).collect()
136}
137
138#[cfg(all(feature = "parse-cfg", feature = "server"))]
139fn collect_endpoints(endpoint_configs: Vec<Box<dyn EndpointConfig>>) -> Result<Vec<Box<dyn Endpoint + Send>>, Error> {
140 endpoint_configs.iter().map(|cfg| cfg.to_endpoint()).collect()
141}