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
use super::*;

pub trait ServicePortExt {
    /// Construct new `ServicePort`
    ///
    fn new(name: impl ToString, port: i32) -> Self;

    /// Set targetPort
    ///
    fn target_port(self, port: impl ToIntOrString) -> Self;

    /// Set protocol
    ///
    fn protocol(self, protocol: impl ToString) -> Self;

    /// Create UDP ServicePort
    ///
    fn udp(name: impl ToString, port: i32) -> Self
    where
        Self: std::marker::Sized,
    {
        Self::new(name, port).protocol("UDP")
    }

    /// Create SCTP ServicePort
    ///
    fn sctp(name: impl ToString, port: i32) -> Self
    where
        Self: std::marker::Sized,
    {
        Self::new(name, port).protocol("SCTP")
    }
}

impl ServicePortExt for corev1::ServicePort {
    fn new(name: impl ToString, port: i32) -> Self {
        let name = Some(name.to_string());
        Self {
            name,
            port,
            // app_protocol: todo!(),
            // node_port: todo!(),
            // protocol: todo!(),
            // target_port: todo!(),
            ..default()
        }
    }

    fn target_port(self, port: impl ToIntOrString) -> Self {
        let target_port = Some(port.to_int_or_string());
        Self {
            target_port,
            ..self
        }
    }

    fn protocol(self, protocol: impl ToString) -> Self {
        let protocol = Some(protocol.to_string());
        Self { protocol, ..self }
    }
}

pub trait ToIntOrString {
    fn to_int_or_string(self) -> intstr::IntOrString;
}

impl ToIntOrString for i32 {
    fn to_int_or_string(self) -> intstr::IntOrString {
        intstr::IntOrString::Int(self)
    }
}

impl ToIntOrString for String {
    fn to_int_or_string(self) -> intstr::IntOrString {
        intstr::IntOrString::String(self)
    }
}

impl ToIntOrString for &str {
    fn to_int_or_string(self) -> intstr::IntOrString {
        intstr::IntOrString::String(self.to_string())
    }
}