taxy_api/
port.rs

1use crate::{
2    id::ShortId,
3    multiaddr::Multiaddr,
4    tls::{TlsState, TlsTermination},
5};
6use serde_derive::{Deserialize, Serialize};
7use std::{
8    net::IpAddr,
9    time::{Duration, SystemTime},
10};
11use utoipa::ToSchema;
12
13#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
14#[serde(rename_all = "snake_case")]
15pub enum SocketState {
16    Listening,
17    Inactive,
18    AddressAlreadyInUse,
19    PermissionDenied,
20    AddressNotAvailable,
21    Error,
22    #[default]
23    Unknown,
24}
25
26#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
27pub struct PortStatus {
28    pub state: PortState,
29    #[serde(
30        serialize_with = "serialize_started_at",
31        deserialize_with = "deserialize_started_at"
32    )]
33    #[schema(value_type = Option<u64>)]
34    pub started_at: Option<SystemTime>,
35}
36
37#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
38pub struct PortState {
39    pub socket: SocketState,
40    pub tls: Option<TlsState>,
41}
42
43fn serialize_started_at<S>(
44    started_at: &Option<SystemTime>,
45    serializer: S,
46) -> Result<S::Ok, S::Error>
47where
48    S: serde::Serializer,
49{
50    if let Some(started_at) = started_at {
51        let started_at = started_at
52            .duration_since(SystemTime::UNIX_EPOCH)
53            .unwrap()
54            .as_secs();
55        serializer.serialize_some(&started_at)
56    } else {
57        serializer.serialize_none()
58    }
59}
60
61fn deserialize_started_at<'de, D>(deserializer: D) -> Result<Option<SystemTime>, D::Error>
62where
63    D: serde::Deserializer<'de>,
64{
65    use serde::Deserialize;
66    let started_at = Option::<u64>::deserialize(deserializer)?;
67    if let Some(started_at) = started_at {
68        Ok(Some(
69            SystemTime::UNIX_EPOCH + Duration::from_secs(started_at),
70        ))
71    } else {
72        Ok(None)
73    }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
77pub struct UpstreamServer {
78    #[schema(value_type = String, example = "/dns/example.com/tcp/8080")]
79    pub addr: Multiaddr,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
83pub struct PortEntry {
84    pub id: ShortId,
85    #[schema(inline)]
86    #[serde(flatten)]
87    pub port: Port,
88}
89
90impl From<(ShortId, Port)> for PortEntry {
91    fn from((id, port): (ShortId, Port)) -> Self {
92        Self { id, port }
93    }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
97pub struct Port {
98    #[serde(default = "default_active", skip_serializing_if = "is_true")]
99    pub active: bool,
100    #[serde(default, skip_serializing_if = "String::is_empty")]
101    pub name: String,
102    #[schema(value_type = String, example = "/ip4/127.0.0.1/tcp/8080")]
103    pub listen: Multiaddr,
104    #[serde(flatten, default)]
105    pub opts: PortOptions,
106}
107
108fn default_active() -> bool {
109    true
110}
111
112fn is_true(b: &bool) -> bool {
113    *b
114}
115
116impl From<PortEntry> for (ShortId, Port) {
117    fn from(entry: PortEntry) -> Self {
118        (entry.id, entry.port)
119    }
120}
121
122#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
123pub struct PortOptions {
124    #[serde(default, skip_serializing_if = "Option::is_none")]
125    pub tls_termination: Option<TlsTermination>,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
129pub struct NetworkInterface {
130    pub name: String,
131    pub addrs: Vec<NetworkAddr>,
132    pub mac: Option<String>,
133}
134
135#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
136pub struct NetworkAddr {
137    #[schema(value_type = String, example = "127.0.0.1")]
138    pub ip: IpAddr,
139    #[schema(value_type = String, example = "255.255.255.0")]
140    pub mask: Option<IpAddr>,
141}