1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Global configuration for this crate.
//!
//! You may change the configuration by calling `set_config` function.
//!
//! # Example
//! ```rust
//! use tcp_handler::config::{Config, set_config};
//!
//! # fn main() {
//! set_config(Config::default());
//! # }
//! ```

use std::sync::RwLock;

/// Global configuration.
///
/// # Example
/// ```rust
/// use tcp_handler::config::Config;
///
/// # fn main() {
/// let config = Config::default();
/// # let _ = config;
/// # }
/// ```
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Config {
    /// `max_packet_size` is the maximum size of a packet in bytes.
    /// It is used to limit the size of a packet that can be received or sent.
    /// Default value is `1 << 20`.
    ///
    /// # Example
    /// ```rust
    /// use tcp_handler::config::Config;
    ///
    /// # fn main() {
    /// let config = Config {
    ///     max_packet_size: 1 << 10,
    /// };
    /// # let _ = config;
    /// # }
    /// ```
    pub max_packet_size: usize,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            max_packet_size: 1 << 20,
        }
    }
}

static CONFIG: RwLock<Config> = RwLock::new(Config {
    max_packet_size: 1 << 20,
});

/// Sets the global configuration.
///
/// This function is recommended to only be called once during initialization.
///
/// # Example
/// ```rust
/// use tcp_handler::config::{Config, set_config};
///
/// # fn main() {
/// set_config(Config::default());
/// # }
/// ```
#[inline]
pub fn set_config(config: Config) {
    let mut c = CONFIG.write().unwrap();
    *c = config;
}

/// Gets the global configuration.
///
/// # Example
/// ```rust
/// use tcp_handler::config::get_config;
///
/// # fn main() {
/// let config = get_config();
/// # let _ = config;
/// # }
/// ```
#[inline]
pub fn get_config() -> Config {
    let c = CONFIG.read().unwrap();
    (*c).clone()
}

/// A cheaper shortcut of
/// ```rust,ignore
/// get_config().max_packet_size
/// ```
#[inline]
pub fn get_max_packet_size() -> usize {
    let c = CONFIG.read().unwrap();
    (*c).max_packet_size
}

#[cfg(test)]
mod test {
    use crate::config::{Config, get_max_packet_size, set_config};

    #[test]
    fn get() {
        let _ = get_max_packet_size();
    }

    #[test]
    fn set() {
        set_config(Config { max_packet_size: 1 });
        assert_eq!(1, get_max_packet_size());
    }

    #[test]
    fn set_twice() {
        set_config(Config { max_packet_size: 1 });
        assert_eq!(1, get_max_packet_size());
        set_config(Config { max_packet_size: 2 });
        assert_eq!(2, get_max_packet_size());
    }
}