net_reporter_api/api/http_clients/
http_client.rs

1use ion_rs;
2
3use ion_rs::IonReader;
4use ion_rs::IonType;
5use ion_rs::IonWriter;
6
7use ion_rs::ReaderBuilder;
8use ion_rs::StreamItem;
9
10use net_core_api::core::api::API;
11use net_core_api::core::encoder_api::Encoder;
12use net_core_api::core::decoder_api::Decoder;
13use net_core_api::core::typed_api::Typed;
14
15const DATA_TYPE: &str = "http_client";
16
17#[derive(Debug, PartialEq, Eq, Clone)]
18pub struct HttpClientDTO {
19    endpoint: String,
20    user_agent: Option<String>,
21    requests_amount: i64,
22}
23impl API for HttpClientDTO { }
24
25impl HttpClientDTO {
26    pub fn new(endpoint: &str, user_agent: Option<&str>, requests_amount: i64) -> Self {
27        HttpClientDTO {
28            endpoint: endpoint.to_string(),
29            user_agent: user_agent.map(|user_agent| user_agent.to_string()),
30            requests_amount,
31        }
32    }
33
34    pub fn get_endpoint(&self) -> &str {
35        &self.endpoint
36    }
37
38    pub fn get_user_agent(&self) -> Option<&str> {
39        self.user_agent.as_deref()
40    }
41
42    pub fn get_requests_amount(&self) -> i64 {
43        self.requests_amount
44    }
45}
46
47impl Encoder for HttpClientDTO {
48    fn encode(&self) -> Vec<u8> {
49        let buffer: Vec<u8> = Vec::new();
50
51        let binary_writer_builder = ion_rs::BinaryWriterBuilder::new();
52        let mut writer = binary_writer_builder.build(buffer.clone()).unwrap();
53        
54        writer.step_in(IonType::Struct).expect("Error while creating an ion struct");
55        
56        writer.set_field_name("endpoint");
57        writer.write_string(&self.endpoint).unwrap();
58
59        writer.set_field_name("user_agent");
60        match &self.user_agent {
61            Some(user_agent) => writer.write_string(user_agent).unwrap(),
62            None => writer.write_null(IonType::String).unwrap(),
63        }
64
65        writer.set_field_name("requests_amount");
66        writer.write_i64(self.requests_amount).unwrap();
67
68        writer.step_out().unwrap();
69        writer.flush().unwrap();
70
71        writer.output().as_slice().into()
72    }
73}
74
75impl Decoder for HttpClientDTO {
76    fn decode(data: &[u8]) -> Self {
77        let mut binary_user_reader = ReaderBuilder::new().build(data).unwrap();
78        binary_user_reader.next().unwrap();
79        binary_user_reader.step_in().unwrap();
80
81        binary_user_reader.next().unwrap();
82        let binding = binary_user_reader.read_string().unwrap();
83        let endpoint = binding.text();
84
85        binary_user_reader.next().unwrap();
86
87        let user_agent = match binary_user_reader.current() {
88            StreamItem::Value(_) => {
89                let binding = binary_user_reader.read_string().unwrap();
90                Some(binding.text().to_string())
91            },
92            _ => None,
93        };
94
95        binary_user_reader.next().unwrap();
96        let requests_amount = binary_user_reader.read_i64().unwrap();
97
98        binary_user_reader.step_out().unwrap();
99
100        HttpClientDTO::new(endpoint, user_agent.as_deref(), requests_amount)
101    }
102}
103
104impl Typed for HttpClientDTO {
105    fn get_data_type() -> &'static str {
106        DATA_TYPE
107    }
108    fn get_type(&self) -> &str {
109        Self::get_data_type()
110    }
111}
112
113
114#[cfg(test)]
115mod tests {
116    use ion_rs::IonType;
117    use ion_rs::IonReader;
118    use ion_rs::ReaderBuilder;
119    use ion_rs::StreamItem;
120    
121    use net_core_api::core::encoder_api::Encoder;
122    use net_core_api::core::decoder_api::Decoder;
123
124    use crate::api::http_clients::http_client::HttpClientDTO;
125
126    #[test]
127    fn reader_correctly_read_encoded_http_client() {
128        const ENDPOINT: &str = "0.0.0.0";
129        const USER_AGENT: &str = "Mozilla/5.0";
130        const REQUESTS_AMOUNT: i64 = 123123;
131        let http_client = HttpClientDTO::new(ENDPOINT, Some(USER_AGENT), REQUESTS_AMOUNT);
132        let mut binary_user_reader = ReaderBuilder::new().build(http_client.encode()).unwrap();
133
134        assert_eq!(StreamItem::Value(IonType::Struct), binary_user_reader.next().unwrap());
135        binary_user_reader.step_in().unwrap();
136        
137        assert_eq!(StreamItem::Value(IonType::String), binary_user_reader.next().unwrap());
138        assert_eq!("endpoint", binary_user_reader.field_name().unwrap());
139        assert_eq!(ENDPOINT,  binary_user_reader.read_string().unwrap().text());
140
141        assert_eq!(StreamItem::Value(IonType::String), binary_user_reader.next().unwrap());
142        assert_eq!("user_agent", binary_user_reader.field_name().unwrap());
143        assert_eq!(USER_AGENT,  binary_user_reader.read_string().unwrap());
144
145        assert_eq!(StreamItem::Value(IonType::Int), binary_user_reader.next().unwrap());
146        assert_eq!("requests_amount", binary_user_reader.field_name().unwrap());
147        assert_eq!(REQUESTS_AMOUNT,  binary_user_reader.read_i64().unwrap());
148
149        binary_user_reader.step_out().unwrap();
150    }
151
152    #[test]
153    fn endec_http_client() {
154        const ENDPOINT: &str = "0.0.0.0";
155        const USER_AGENT: &str = "Mozilla/5.0";
156        const REQUESTS_AMOUNT: i64 = 123123;
157        let http_client = HttpClientDTO::new(ENDPOINT, Some(USER_AGENT), REQUESTS_AMOUNT);
158        assert_eq!(http_client, HttpClientDTO::decode(&http_client.encode()));
159    }
160}