arcs_ctf_yaml_parser/deploy/
structs.rs1use std::fmt::{Debug, Display};
2use std::path::PathBuf;
3
4use serde::{Serialize, Serializer};
5
6#[derive(Debug, Clone, PartialEq, Serialize)]
7pub struct DeployLink {
8 #[serde(rename = "type")]
9 pub deploy_target: DeployTargetType,
10 #[serde(rename = "location")]
11 pub link: String,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DeployTargetType { Web, Admin, Nc, Static }
16
17impl DeployTargetType {
18 pub fn is_web(&self) -> bool {
19 matches!(self, Self::Web)
20 }
21 pub fn is_admin(&self) -> bool {
22 matches!(self, Self::Admin)
23 }
24 pub fn is_nc(&self) -> bool {
25 matches!(self, Self::Nc)
26 }
27 pub fn is_static(&self) -> bool {
28 matches!(self, Self::Static)
29 }
30
31 pub fn as_str(&self) -> &'static str {
32 match self {
33 Self::Web => "web",
34 Self::Admin => "admin",
35 Self::Nc => "nc",
36 Self::Static => "static",
37 }
38 }
39
40 pub fn resource_type(&self) -> &'static str {
41 match self {
42 Self::Web => "Web server",
43 Self::Admin => "Admin bot server",
44 Self::Nc => "Netcat server",
45 Self::Static => "Static file",
46 }
47 }
48}
49
50impl Display for DeployTargetType {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 write!(f, "{}", self.as_str())
53 }
54}
55
56impl Serialize for DeployTargetType {
57 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58 where
59 S: Serializer {
60 serializer.serialize_str(self.as_str())
61 }
62}
63
64#[derive(Clone, PartialEq)]
65pub struct DeployOptions {
66 pub web: Option<DeployTarget>,
67 pub admin: Option<DeployTarget>,
68 pub nc: Option<DeployTarget>,
69}
70
71impl IntoIterator for DeployOptions {
72 type IntoIter = std::iter::Flatten<std::array::IntoIter<Option<(DeployTarget, DeployTargetType)>, 3>>;
73 type Item = (DeployTarget, DeployTargetType);
74
75 fn into_iter(self) -> Self::IntoIter {
76 use DeployTargetType::*;
77 [
78 self.web.map(|v| (v, Web)),
79 self.admin.map(|v| (v, Admin)),
80 self.nc.map(|v| (v, Nc)),
81 ].into_iter().flatten()
82 }
83}
84
85#[derive(Clone, PartialEq)]
86pub struct DeployTarget {
87 pub expose: NetworkProtocol,
88 pub build: PathBuf,
89 pub replicas: u8,
90}
91
92#[derive(Debug, Clone, Copy, PartialEq)]
93pub enum NetworkProtocol {
94 Tcp(u32),
95 Udp(u32),
96}
97impl NetworkProtocol {
98 pub fn port(&self) -> u32 {
99 match *self { Self::Tcp(n) | Self::Udp(n) => n }
100 }
101 pub fn is_tcp(&self) -> bool {
102 matches!(self, Self::Tcp(_))
103 }
104 pub fn is_udp(&self) -> bool {
105 matches!(self, Self::Udp(_))
106 }
107}
108
109impl Debug for DeployTarget {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "Target< {} ", self.expose.port())?;
112 if self.expose.is_tcp() {
113 write!(f, "(tcp)")
114 } else {
115 write!(f, "(udp)")
116 }?;
117
118 write!(
119 f,
120 " ({}) ",
121 format_args!(
122 "{} {}",
123 self.replicas,
124 if self.replicas == 1 { "replica" } else { "replicas" },
125 ),
126 )?;
127
128 write!(
129 f,
130 " @ {}>",
131 self.build.display(),
132 )
133 }
134}
135
136impl Debug for DeployOptions {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 let mut options_formatter = f.debug_struct("DeployOptions");
139 if let Some(web) = &self.web {
140 options_formatter.field("web", web);
141 }
142 if let Some(admin) = &self.admin {
143 options_formatter.field("admin", admin);
144 }
145 if let Some(nc) = &self.nc {
146 options_formatter.field("nc", nc);
147 }
148 options_formatter.finish()
149 }
150}