tcp_handler/
config.rs

1//! Global configuration for this [`crate`].
2//!
3//! You may change the configuration by calling [`set_config`] function.
4//!
5//! # Example
6//! ```rust
7//! use tcp_handler::config::{Config, set_config};
8//!
9//! # fn main() {
10//! set_config(Config::default());
11//! # }
12//! ```
13
14use std::sync::RwLock;
15use once_cell::sync::Lazy;
16
17/// Global configuration.
18///
19/// # Example
20/// ```rust
21/// use tcp_handler::config::Config;
22///
23/// # fn main() {
24/// let config = Config::default();
25/// # let _ = config;
26/// # }
27/// ```
28#[derive(Debug, Clone, Copy, Eq, PartialEq)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(default))]
30pub struct Config {
31    /// `max_packet_size` is the maximum size of a packet in bytes.
32    /// It is used to limit the size of a packet that can be received or sent.
33    ///
34    /// The default value is `1 << 20`.
35    ///
36    /// # Example
37    /// ```rust
38    /// use tcp_handler::config::Config;
39    ///
40    /// # fn main() {
41    /// let config = Config {
42    ///     max_packet_size: 1 << 10,
43    ///     ..Config::default()
44    /// };
45    /// # let _ = config;
46    /// # }
47    /// ```
48    pub max_packet_size: usize,
49
50    /// `compression` is the [`flate2::Compression`] level when sending packets.
51    ///
52    /// # Example
53    /// ```rust
54    /// use tcp_handler::config::Config;
55    /// use tcp_handler::Compression;
56    ///
57    /// # fn main() {
58    /// let config = Config {
59    ///     compression: Compression::fast(),
60    ///     ..Config::default()
61    /// };
62    /// # let _ = config;
63    /// # }
64    /// ```
65    #[cfg(feature = "compression")]
66    #[cfg_attr(docsrs, cfg(feature = "compression"))]
67    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_compression", deserialize_with = "deserialize_compression"))]
68    pub compression: flate2::Compression,
69}
70
71#[cfg(feature = "serde")]
72fn serialize_compression<S: serde::Serializer>(compression: &flate2::Compression, serializer: S) -> Result<S::Ok, S::Error> {
73    <u32 as serde::Serialize>::serialize(&(compression.level()), serializer)
74}
75
76#[cfg(feature = "serde")]
77fn deserialize_compression<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<flate2::Compression, D::Error> {
78    <u32 as serde::Deserialize>::deserialize(deserializer).map(|l| flate2::Compression::new(l))
79}
80
81impl Default for Config {
82    fn default() -> Self {
83        Self {
84            max_packet_size: 1 << 20,
85            #[cfg(feature = "compression")]
86            compression: flate2::Compression::default(),
87        }
88    }
89}
90
91static CONFIG: Lazy<RwLock<Config>> = Lazy::new(|| RwLock::new(Config::default()));
92
93/// Set the global configuration.
94///
95/// This function is recommended to only be called once during initialization.
96///
97/// # Example
98/// ```rust
99/// use tcp_handler::config::{Config, set_config};
100///
101/// # fn main() {
102/// set_config(Config::default());
103/// # }
104/// ```
105#[inline]
106pub fn set_config(config: Config) {
107    let mut c = CONFIG.write().unwrap();
108    *c = config;
109}
110
111/// Get the global configuration.
112///
113/// # Example
114/// ```rust
115/// use tcp_handler::config::get_config;
116///
117/// # fn main() {
118/// let config = get_config();
119/// # let _ = config;
120/// # }
121/// ```
122#[inline]
123pub fn get_config() -> Config {
124    let c = CONFIG.read().unwrap();
125    (*c).clone()
126}
127
128/// A cheaper shortcut of
129/// ```rust,ignore
130/// get_config().max_packet_size
131/// ```
132#[inline]
133pub fn get_max_packet_size() -> usize {
134    let c = CONFIG.read().unwrap();
135    (*c).max_packet_size
136}
137
138/// A cheaper shortcut of
139/// ```rust,ignore
140/// get_config().compression
141/// ```
142#[cfg(feature = "compression")]
143#[cfg_attr(docsrs, cfg(feature = "compression"))]
144#[inline]
145pub fn get_compression() -> flate2::Compression {
146    let c = CONFIG.read().unwrap();
147    (*c).compression
148}
149
150#[cfg(test)]
151mod test {
152    use crate::config::*;
153
154    #[test]
155    fn get() {
156        let _ = get_max_packet_size();
157        let _ = get_compression();
158    }
159
160    #[test]
161    fn set() {
162        set_config(Config { max_packet_size: 1 << 10, ..Config::default() });
163        assert_eq!(1 << 10, get_max_packet_size());
164    }
165
166    #[test]
167    fn set_twice() {
168        set_config(Config { max_packet_size: 1 << 10, ..Config::default() });
169        assert_eq!(1 << 10, get_max_packet_size());
170        set_config(Config { max_packet_size: 2 << 10, ..Config::default() });
171        assert_eq!(2 << 10, get_max_packet_size());
172    }
173
174    #[cfg(feature = "serde")]
175    #[test]
176    fn serde() {
177        let config = Config { max_packet_size: 1 << 10, ..Config::default() };
178        let serialized = serde_json::to_string(&config).unwrap();
179        let deserialized: Config = serde_json::from_str(&serialized).unwrap();
180        assert_eq!(config, deserialized);
181    }
182}