Fix types causing json deserializations errors

This commit is contained in:
Maxime Van Hees 2025-07-30 16:04:41 +02:00
parent abfb79b0cd
commit caa47982c3
2 changed files with 116 additions and 46 deletions

View File

@ -232,6 +232,21 @@ impl fmt::Display for Boot {
} }
} }
#[derive(Debug, Deserialize, Clone)]
#[serde(untagged)]
pub enum Os {
Single(String),
Multiple(Vec<String>),
}
impl Os {
pub fn to_vec(&self) -> Vec<String> {
match self {
Os::Single(s) => vec![s.clone()],
Os::Multiple(v) => v.clone(),
}
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct RescueWrapped { pub struct RescueWrapped {
pub rescue: Rescue, pub rescue: Rescue,
@ -243,12 +258,12 @@ pub struct Rescue {
pub server_ip: String, pub server_ip: String,
pub server_ipv6_net: String, pub server_ipv6_net: String,
pub server_number: i32, pub server_number: i32,
#[serde(deserialize_with = "string_or_seq_string")] pub os: Os,
pub os: Vec<String>,
pub active: bool, pub active: bool,
pub password: Option<String>, pub password: Option<String>,
pub authorized_key: Vec<String>, #[serde(rename = "authorized_key")]
pub host_key: Vec<String>, pub authorized_keys: Vec<RescueKey>,
pub host_key: Vec<HostKey>,
} }
impl Rescue { impl Rescue {
@ -260,10 +275,15 @@ impl Rescue {
r.server_ipv6_net.clone() r.server_ipv6_net.clone()
}) })
.with_get("server_number", |r: &mut Rescue| r.server_number) .with_get("server_number", |r: &mut Rescue| r.server_number)
.with_get("os", |r: &mut Rescue| r.os.clone()) .with_get("os", |r: &mut Rescue| r.os.to_vec())
.with_get("active", |r: &mut Rescue| r.active) .with_get("active", |r: &mut Rescue| r.active)
.with_get("password", |r: &mut Rescue| r.password.clone()) .with_get("password", |r: &mut Rescue| r.password.clone())
.with_get("authorized_key", |r: &mut Rescue| r.authorized_key.clone()) .with_get("authorized_keys", |r: &mut Rescue| {
r.authorized_keys
.iter()
.map(|k| rhai::Dynamic::from(k.key.clone()))
.collect::<rhai::Array>()
})
.with_get("host_key", |r: &mut Rescue| r.host_key.clone()) .with_get("host_key", |r: &mut Rescue| r.host_key.clone())
.on_print(|r: &mut Rescue| r.to_string()) .on_print(|r: &mut Rescue| r.to_string())
.with_fn("pretty_print", |r: &mut Rescue| r.to_string()); .with_fn("pretty_print", |r: &mut Rescue| r.to_string());
@ -272,13 +292,30 @@ impl Rescue {
impl fmt::Display for Rescue { impl fmt::Display for Rescue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( let mut table = Table::new();
f, table.add_row(row!["Property", "Value"]);
"OS: {}, Active: {}, Keys: {}", table.add_row(row!["Server IP", self.server_ip]);
self.os.join(", "), table.add_row(row!["Server IPv6 Net", self.server_ipv6_net]);
self.active, table.add_row(row!["Server Number", self.server_number.to_string()]);
self.authorized_key.join(", ") table.add_row(row!["OS", self.os.to_vec().join(", ")]);
) table.add_row(row!["Active", self.active.to_string()]);
table.add_row(row!["Password", self.password.as_deref().unwrap_or("N/A")]);
let authorized_keys: Vec<String> = self
.authorized_keys
.iter()
.filter_map(|key| key.key.fingerprint.clone())
.collect();
table.add_row(row!["Authorized Keys", authorized_keys.join("\n")]);
let host_keys: Vec<String> = self
.host_key
.iter()
.filter_map(|key| key.fingerprint.clone())
.collect();
table.add_row(row!["Host Keys", host_keys.join("\n")]);
write!(f, "{}", table)
} }
} }
@ -294,8 +331,9 @@ pub struct Linux {
pub lang: Vec<String>, pub lang: Vec<String>,
pub active: bool, pub active: bool,
pub password: Option<String>, pub password: Option<String>,
pub authorized_key: Vec<String>, #[serde(rename = "authorized_key")]
pub host_key: Vec<String>, pub authorized_keys: Vec<RescueKey>,
pub host_key: Vec<HostKey>,
} }
impl Linux { impl Linux {
@ -309,7 +347,12 @@ impl Linux {
.with_get("lang", |l: &mut Linux| l.lang.clone()) .with_get("lang", |l: &mut Linux| l.lang.clone())
.with_get("active", |l: &mut Linux| l.active) .with_get("active", |l: &mut Linux| l.active)
.with_get("password", |l: &mut Linux| l.password.clone()) .with_get("password", |l: &mut Linux| l.password.clone())
.with_get("authorized_key", |l: &mut Linux| l.authorized_key.clone()) .with_get("authorized_keys", |l: &mut Linux| {
l.authorized_keys
.iter()
.map(|k| rhai::Dynamic::from(k.key.clone()))
.collect::<rhai::Array>()
})
.with_get("host_key", |l: &mut Linux| l.host_key.clone()) .with_get("host_key", |l: &mut Linux| l.host_key.clone())
.on_print(|l: &mut Linux| l.to_string()) .on_print(|l: &mut Linux| l.to_string())
.with_fn("pretty_print", |l: &mut Linux| l.to_string()); .with_fn("pretty_print", |l: &mut Linux| l.to_string());
@ -318,13 +361,30 @@ impl Linux {
impl fmt::Display for Linux { impl fmt::Display for Linux {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( let mut table = Table::new();
f, table.add_row(row!["Property", "Value"]);
"Dist: {}, Lang: {}, Active: {}", table.add_row(row!["Server IP", self.server_ip]);
self.dist.join(", "), table.add_row(row!["Server IPv6 Net", self.server_ipv6_net]);
self.lang.join(", "), table.add_row(row!["Server Number", self.server_number.to_string()]);
self.active table.add_row(row!["Distribution", self.dist.join(", ")]);
) table.add_row(row!["Language", self.lang.join(", ")]);
table.add_row(row!["Active", self.active.to_string()]);
table.add_row(row!["Password", self.password.as_deref().unwrap_or("N/A")]);
let authorized_keys: Vec<String> = self
.authorized_keys
.iter()
.filter_map(|key| key.key.fingerprint.clone())
.collect();
table.add_row(row!["Authorized Keys", authorized_keys.join("\n")]);
let host_keys: Vec<String> = self
.host_key
.iter()
.filter_map(|key| key.fingerprint.clone())
.collect();
table.add_row(row!["Host Keys", host_keys.join("\n")]);
write!(f, "{}", table)
} }
} }
@ -1043,20 +1103,20 @@ pub struct AuthorizedKeyWrapper {
#[derive(Debug, Deserialize, Clone, CustomType)] #[derive(Debug, Deserialize, Clone, CustomType)]
#[rhai_type(extra = Self::build_rhai_type)] #[rhai_type(extra = Self::build_rhai_type)]
pub struct AuthorizedKey { pub struct AuthorizedKey {
pub name: String, pub name: Option<String>,
pub fingerprint: String, pub fingerprint: Option<String>,
#[serde(rename = "type")] #[serde(rename = "type")]
pub key_type: String, pub key_type: Option<String>,
pub size: i32, pub size: Option<i32>,
} }
impl From<SshKey> for AuthorizedKey { impl From<SshKey> for AuthorizedKey {
fn from(key: SshKey) -> Self { fn from(key: SshKey) -> Self {
Self { Self {
name: key.name, name: Some(key.name),
fingerprint: key.fingerprint, fingerprint: Some(key.fingerprint),
key_type: key.key_type, key_type: Some(key.key_type),
size: key.size, size: Some(key.size),
} }
} }
} }
@ -1130,10 +1190,16 @@ pub struct HostKeyWrapper {
#[derive(Debug, Deserialize, Clone, CustomType)] #[derive(Debug, Deserialize, Clone, CustomType)]
#[rhai_type(extra = Self::build_rhai_type)] #[rhai_type(extra = Self::build_rhai_type)]
pub struct HostKey { pub struct HostKey {
pub fingerprint: String, pub fingerprint: Option<String>,
#[serde(rename = "type")] #[serde(rename = "type")]
pub key_type: String, pub key_type: Option<String>,
pub size: i32, pub size: Option<i32>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct RescueKey {
pub key: HostKey,
} }
impl HostKey { impl HostKey {
@ -1466,10 +1532,10 @@ impl fmt::Display for AuctionTransaction {
authorized_keys_table.add_row(row![b => "Name", "Fingerprint", "Type", "Size"]); authorized_keys_table.add_row(row![b => "Name", "Fingerprint", "Type", "Size"]);
for key in &self.authorized_key { for key in &self.authorized_key {
authorized_keys_table.add_row(row![ authorized_keys_table.add_row(row![
key.key.name, key.key.name.as_deref().unwrap_or("N/A"),
key.key.fingerprint, key.key.fingerprint.as_deref().unwrap_or("N/A"),
key.key.key_type, key.key.key_type.as_deref().unwrap_or("N/A"),
key.key.size key.key.size.map_or("N/A".to_string(), |s| s.to_string())
]); ]);
} }
table.add_row(row!["Authorized Keys", authorized_keys_table]); table.add_row(row!["Authorized Keys", authorized_keys_table]);
@ -1477,7 +1543,11 @@ impl fmt::Display for AuctionTransaction {
let mut host_keys_table = Table::new(); let mut host_keys_table = Table::new();
host_keys_table.add_row(row![b => "Fingerprint", "Type", "Size"]); host_keys_table.add_row(row![b => "Fingerprint", "Type", "Size"]);
for key in &self.host_key { for key in &self.host_key {
host_keys_table.add_row(row![key.key.fingerprint, key.key.key_type, key.key.size]); host_keys_table.add_row(row![
key.key.fingerprint.as_deref().unwrap_or("N/A"),
key.key.key_type.as_deref().unwrap_or("N/A"),
key.key.size.map_or("N/A".to_string(), |s| s.to_string())
]);
} }
table.add_row(row!["Host Keys", host_keys_table]); table.add_row(row!["Host Keys", host_keys_table]);

View File

@ -196,10 +196,10 @@ pub fn pretty_print_auction_transactions(transactions: rhai::Array) {
table.add_row(row![b => "Name", "Fingerprint", "Type", "Size"]); table.add_row(row![b => "Name", "Fingerprint", "Type", "Size"]);
for key in &transaction.authorized_key { for key in &transaction.authorized_key {
table.add_row(row![ table.add_row(row![
key.key.name, key.key.name.as_deref().unwrap_or("N/A"),
key.key.fingerprint, key.key.fingerprint.as_deref().unwrap_or("N/A"),
key.key.key_type, key.key.key_type.as_deref().unwrap_or("N/A"),
key.key.size key.key.size.map_or("N/A".to_string(), |s| s.to_string())
]); ]);
} }
table table
@ -210,9 +210,9 @@ pub fn pretty_print_auction_transactions(transactions: rhai::Array) {
table.add_row(row![b => "Fingerprint", "Type", "Size"]); table.add_row(row![b => "Fingerprint", "Type", "Size"]);
for key in &transaction.host_key { for key in &transaction.host_key {
table.add_row(row![ table.add_row(row![
key.key.fingerprint, key.key.fingerprint.as_deref().unwrap_or("N/A"),
key.key.key_type, key.key.key_type.as_deref().unwrap_or("N/A"),
key.key.size key.key.size.map_or("N/A".to_string(), |s| s.to_string())
]); ]);
} }
table table