clashctl_core/model/
connection.rs

1use serde::{Deserialize, Serialize};
2
3use crate::model::{RuleType, TimeType};
4
5#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
6#[serde(rename_all = "camelCase")]
7pub struct Metadata {
8    #[serde(rename = "type")]
9    pub connection_type: String,
10
11    #[serde(rename = "sourceIP")]
12    pub source_ip: String,
13    pub source_port: String,
14
15    #[serde(rename = "destinationIP")]
16    pub destination_ip: String,
17    pub destination_port: String,
18    pub host: String,
19    pub network: String,
20}
21
22#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
23#[serde(rename_all = "camelCase")]
24pub struct Connection {
25    pub id: String,
26    pub upload: u64,
27    pub download: u64,
28    pub metadata: Metadata,
29    pub rule: RuleType,
30    pub rule_payload: String,
31    pub start: TimeType,
32    pub chains: Vec<String>,
33}
34
35#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
36#[serde(rename_all = "camelCase")]
37pub struct Connections {
38    pub connections: Vec<Connection>,
39    pub download_total: u64,
40    pub upload_total: u64,
41}
42
43#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
44pub struct ConnectionWithSpeed {
45    pub connection: Connection,
46    pub upload: Option<u64>,
47    pub download: Option<u64>,
48}
49
50#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
51pub struct ConnectionsWithSpeed {
52    pub connections: Vec<ConnectionWithSpeed>,
53    pub download_total: u64,
54    pub upload_total: u64,
55}
56
57#[cfg(feature = "deserialize")]
58pub use deserialize::*;
59
60#[cfg(feature = "deserialize")]
61mod deserialize {
62    use chrono::Utc;
63
64    use crate::model::{Connection, ConnectionWithSpeed, Connections, ConnectionsWithSpeed};
65
66    impl Connection {
67        pub fn up_speed(&self) -> Option<u64> {
68            let elapsed = (Utc::now() - self.start).num_seconds();
69            if elapsed <= 0 {
70                None
71            } else {
72                Some(self.upload / elapsed as u64)
73            }
74        }
75
76        pub fn down_speed(&self) -> Option<u64> {
77            let elapsed = (Utc::now() - self.start).num_seconds();
78            if elapsed <= 0 {
79                None
80            } else {
81                Some(self.download / elapsed as u64)
82            }
83        }
84    }
85
86    impl From<Connections> for ConnectionsWithSpeed {
87        fn from(val: Connections) -> Self {
88            Self {
89                connections: val.connections.into_iter().map(Into::into).collect(),
90                download_total: val.download_total,
91                upload_total: val.upload_total,
92            }
93        }
94    }
95
96    impl From<ConnectionsWithSpeed> for Connections {
97        fn from(val: ConnectionsWithSpeed) -> Self {
98            Self {
99                connections: val.connections.into_iter().map(Into::into).collect(),
100                download_total: val.download_total,
101                upload_total: val.upload_total,
102            }
103        }
104    }
105
106    impl From<Connection> for ConnectionWithSpeed {
107        fn from(val: Connection) -> Self {
108            let elapsed = (Utc::now() - val.start).num_seconds();
109            if elapsed <= 0 {
110                Self {
111                    connection: val,
112                    upload: None,
113                    download: None,
114                }
115            } else {
116                Self {
117                    download: Some(val.download / elapsed as u64),
118                    upload: Some(val.upload / elapsed as u64),
119                    connection: val,
120                }
121            }
122        }
123    }
124
125    impl From<ConnectionWithSpeed> for Connection {
126        fn from(val: ConnectionWithSpeed) -> Self {
127            val.connection
128        }
129    }
130}