use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
#[derive(Debug, Deserialize)]
pub(crate) struct NodeVersion<'a> {
pub(crate) version: &'a str,
}
pub type NodeInfo<'a> = NodeInfoInternal<&'a str>;
pub type NodeInfoOwned = NodeInfoInternal<String>;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct NodeInfoInternal<T> {
pub version: T,
pub software: Software<T>,
#[serde(default)]
pub protocols: Vec<T>,
#[serde(default)]
pub services: Services<T>,
#[serde(rename = "openRegistrations", default)]
pub open_registrations: bool,
#[serde(default)]
pub usage: Usage,
#[serde(default)]
pub metadata: Map<String, Value>,
}
#[derive(Debug, PartialEq, Deserialize)]
pub struct LegacyNodeInfo<'a> {
version: &'a str,
software: Software<&'a str>,
#[serde(default)]
services: Services<&'a str>,
#[serde(default)]
protocols: Services<&'a str>,
#[serde(rename = "openRegistrations", default)]
open_registrations: bool,
#[serde(default)]
usage: Usage,
#[serde(default)]
metadata: Map<String, Value>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Software<T> {
pub name: T,
pub version: Option<T>,
pub repository: Option<T>,
pub homepage: Option<T>,
}
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Services<T> {
pub inbound: Vec<T>,
pub outbound: Vec<T>,
}
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Usage {
pub users: Option<Users>,
pub local_posts: Option<i64>,
pub local_comments: Option<i64>,
}
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Users {
pub total: Option<i64>,
pub active_halfyear: Option<i64>,
pub active_month: Option<i64>,
}
impl<'a> Software<&'a str> {
fn to_owned(&self) -> Software<String> {
Software {
name: self.name.to_string(),
version: self.version.map(ToString::to_string),
repository: self.repository.map(ToString::to_string),
homepage: self.homepage.map(ToString::to_string),
}
}
}
impl<'a> Services<&'a str> {
fn to_owned(&self) -> Services<String> {
Services {
inbound: self.inbound.iter().map(ToString::to_string).collect(),
outbound: self.outbound.iter().map(ToString::to_string).collect(),
}
}
}
impl NodeInfo<'_> {
pub fn to_owned(&self) -> NodeInfoOwned {
NodeInfoOwned {
version: self.version.to_string(),
software: self.software.to_owned(),
protocols: self.protocols.iter().map(ToString::to_string).collect(),
services: self.services.to_owned(),
open_registrations: self.open_registrations,
usage: self.usage.clone(),
metadata: self.metadata.clone(),
}
}
}
impl<'a> From<LegacyNodeInfo<'a>> for NodeInfo<'a> {
fn from(other: LegacyNodeInfo<'a>) -> Self {
let mut combined_protocols: Vec<&'a str> = other
.protocols
.inbound
.into_iter()
.chain(other.protocols.outbound)
.collect();
combined_protocols.sort();
combined_protocols.dedup();
NodeInfo {
version: other.version,
software: other.software,
services: other.services,
protocols: combined_protocols,
open_registrations: other.open_registrations,
usage: other.usage,
metadata: other.metadata,
}
}
}
impl<'a> From<LegacyNodeInfo<'a>> for NodeInfoOwned {
fn from(value: LegacyNodeInfo<'a>) -> Self {
NodeInfo::from(value).to_owned()
}
}