ph_mobile_network/
mobile_network.rs

1use std::fmt;
2
3use crate::{
4    dito::Dito,
5    errors::MobileNetworkError,
6    globals::{
7        dito_prefixes::DITO_PREFIXES, globe_prefixes::GLOBE_PREFIXES,
8        smart_prefixes::SMART_PREFIXES, sun_prefixes::SUN_PREFIXES, tnt_prefixes::TNT_PREFIXES,
9    },
10    globe::Globe,
11    smart::Smart,
12    sun::Sun,
13    talk_n_text::TNT,
14    validate::Validate,
15};
16
17pub enum MobileNetwork {
18    Globe(Globe),
19    Smart(Smart),
20    Sun(Sun),
21    TNT(TNT),
22    Dito(Dito),
23    Invalid(String),
24}
25
26impl MobileNetwork {
27    pub fn get(number: &str) -> Result<Self, MobileNetworkError> {
28        let prefix = &number[..number.len().min(4)];
29
30        let globe_prefixes = GLOBE_PREFIXES.try_lock().map_err(|_| {
31            MobileNetworkError::MutexError("Failed to lock GLOBE_PREFIXES".to_string())
32        })?;
33
34        let smart_prefixes = SMART_PREFIXES.try_lock().map_err(|_| {
35            MobileNetworkError::MutexError("Failed to lock SMART_PREFIXES".to_string())
36        })?;
37
38        let sun_prefixes = SUN_PREFIXES.try_lock().map_err(|_| {
39            MobileNetworkError::MutexError("Failed to lock SUN_PREFIXES".to_string())
40        })?;
41
42        let talk_n_text_prefixes = TNT_PREFIXES.try_lock().map_err(|_| {
43            MobileNetworkError::MutexError("Failed to lock TALK_N_TEXT_PREFIXES".to_string())
44        })?;
45
46        let dito_prefixes = DITO_PREFIXES.try_lock().map_err(|_| {
47            MobileNetworkError::MutexError("Failed to lock DITO_PREFIXES".to_string())
48        })?;
49
50        if globe_prefixes.contains(&prefix) {
51            Globe::new(&globe_prefixes).map(MobileNetwork::Globe)
52        } else if smart_prefixes.contains(&prefix) {
53            Smart::new(&smart_prefixes).map(MobileNetwork::Smart)
54        } else if sun_prefixes.contains(&prefix) {
55            Sun::new(&sun_prefixes).map(MobileNetwork::Sun)
56        } else if talk_n_text_prefixes.contains(&prefix) {
57            TNT::new(&talk_n_text_prefixes).map(MobileNetwork::TNT)
58        } else if dito_prefixes.contains(&prefix) {
59            Dito::new(&dito_prefixes).map(MobileNetwork::Dito)
60        } else {
61            Err(MobileNetworkError::UnrecognizedPrefix(prefix.to_string()))
62        }
63    }
64}
65
66impl Validate for MobileNetwork {
67    fn validate(&self, number: &str) -> Result<bool, crate::errors::MobileNetworkError> {
68        match self {
69            MobileNetwork::Globe(globe) => globe.validate(number),
70            MobileNetwork::Smart(smart) => smart.validate(number),
71            MobileNetwork::Sun(sun) => sun.validate(number),
72            MobileNetwork::TNT(tnt) => tnt.validate(number),
73            MobileNetwork::Dito(dito) => dito.validate(number),
74            MobileNetwork::Invalid(text) => {
75                Err(MobileNetworkError::UnrecognizedPrefix(text.clone()))
76            }
77        }
78    }
79}
80
81impl fmt::Display for MobileNetwork {
82    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83        match self {
84            MobileNetwork::Globe(_) => write!(f, "globe"),
85            MobileNetwork::Smart(_) => write!(f, "smart"),
86            MobileNetwork::Sun(_) => write!(f, "sun"),
87            MobileNetwork::TNT(_) => write!(f, "tnt"),
88            MobileNetwork::Dito(_) => write!(f, "dito"),
89            MobileNetwork::Invalid(reason) => write!(f, "invalid ({})", reason),
90        }
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use crate::mutate::*;
97
98    use super::*;
99
100    // Testing setup function that prepares test data and environment
101    fn setup() {
102        // Clear and set up each prefix list before each test
103        reset_dito_prefixes();
104        reset_globe_prefixes();
105        reset_smart_prefixes();
106        reset_sun_prefixes();
107        reset_tnt_prefixes();
108
109        append_dito_prefixes(&["0897", "0898"]);
110        append_globe_prefixes(&["0917", "0918"]);
111        append_smart_prefixes(&["0919", "0920"]);
112        append_sun_prefixes(&["0922", "0923"]);
113        append_tnt_prefixes(&["0930", "0938"]);
114    }
115
116    #[test]
117    fn display_formats_are_correct() {
118        setup();
119        let globe = MobileNetwork::get("09171234567").unwrap();
120        let smart = MobileNetwork::get("09191234567").unwrap();
121        let sun = MobileNetwork::get("09221234567").unwrap();
122        let tnt = MobileNetwork::get("09301234567").unwrap();
123        let dito = MobileNetwork::get("08971234567").unwrap();
124        let invalid = MobileNetwork::Invalid("test".to_string());
125
126        assert_eq!(format!("{}", globe), "globe");
127        assert_eq!(format!("{}", smart), "smart");
128        assert_eq!(format!("{}", sun), "sun");
129        assert_eq!(format!("{}", tnt), "tnt");
130        assert_eq!(format!("{}", dito), "dito");
131        assert_eq!(format!("{}", invalid), "invalid (test)");
132    }
133
134    #[test]
135    fn validate_all_network() {
136        setup();
137        let globe = MobileNetwork::get("09171234567").unwrap();
138
139        assert!(globe.validate("09171234567").is_ok());
140
141        let smart = MobileNetwork::get("09191234567").unwrap();
142        assert!(smart.validate("09191234567").is_ok());
143
144        let sun = MobileNetwork::get("09221234567").unwrap();
145        assert!(sun.validate("09221234567").is_ok());
146
147        let tnt = MobileNetwork::get("09301234567").unwrap();
148        assert!(tnt.validate("09301234567").is_ok());
149
150        let dito = MobileNetwork::get("08971234567").unwrap();
151        assert!(dito.validate("08971234567").is_ok());
152
153        let invalid = MobileNetwork::Invalid("test".to_string());
154        assert!(invalid.validate("any_number").is_err());
155    }
156
157    #[test]
158    fn test_get_globe_network() {
159        setup();
160        let result = MobileNetwork::get("09171234567");
161        assert!(matches!(result, Ok(MobileNetwork::Globe(_))));
162    }
163
164    #[test]
165    fn test_get_smart_network() {
166        setup();
167        let result = MobileNetwork::get("09191234567");
168        assert!(matches!(result, Ok(MobileNetwork::Smart(_))));
169    }
170
171    #[test]
172    fn test_get_sun_network() {
173        setup();
174        let result = MobileNetwork::get("09221234567");
175        assert!(matches!(result, Ok(MobileNetwork::Sun(_))));
176    }
177
178    #[test]
179    fn test_get_tnt_network() {
180        setup();
181        let result = MobileNetwork::get("09301234567");
182        assert!(matches!(result, Ok(MobileNetwork::TNT(_))));
183    }
184
185    #[test]
186    fn test_get_dito_network() {
187        setup();
188        let result = MobileNetwork::get("08971234567");
189        assert!(matches!(result, Ok(MobileNetwork::Dito(_))));
190    }
191
192    #[test]
193    fn test_get_invalid_network() {
194        setup();
195        let result = MobileNetwork::get("09871234567");
196        assert!(matches!(
197            result,
198            Err(MobileNetworkError::UnrecognizedPrefix(_))
199        ));
200    }
201}