diff --git a/crates/configuration/src/shared/types.rs b/crates/configuration/src/shared/types.rs index 5643846c9aa7b6ee0be4c15562b3dfa271934005..0195b299c3e8f0c0eee1d3ea24cc869a7b8daced 100644 --- a/crates/configuration/src/shared/types.rs +++ b/crates/configuration/src/shared/types.rs @@ -1,7 +1,8 @@ -use std::{path::PathBuf, str::FromStr}; +use std::{fmt::Display, path::PathBuf, str::FromStr}; use lazy_static::lazy_static; use regex::Regex; +use serde::Serialize; use url::Url; use super::{errors::ConversionError, resources::Resources}; @@ -15,6 +16,28 @@ pub type Port = u16; /// An alias for a parachain ID. pub type ParaId = u32; +/// Custom type wrapping u128 to add custom Serialization/Deserialization logic because it's not supported +/// issue tracking the problem: https://github.com/toml-rs/toml/issues/540 +#[derive(Debug, Clone, PartialEq)] +pub struct U128(pub(crate) u128); + +impl From<u128> for U128 { + fn from(value: u128) -> Self { + Self(value) + } +} + +impl Serialize for U128 { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + // here we add a prefix to the string to be able to replace the wrapped + // value with "" to a value without "" in the TOML string + serializer.serialize_str(&format!("U128%{}", self.0)) + } +} + /// A chain name. /// It can be constructed for an `&str`, if it fails, it will returns a [`ConversionError`]. /// @@ -30,7 +53,7 @@ pub type ParaId = u32; /// assert_eq!(kusama.as_str(), "kusama"); /// assert_eq!(myparachain.as_str(), "myparachain"); /// ``` -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Chain(String); impl TryFrom<&str> for Chain { @@ -72,7 +95,7 @@ impl Chain { /// assert_eq!(image3.as_str(), "myrepo.com/name:version"); /// assert_eq!(image4.as_str(), "10.15.43.155/name:version"); /// ``` -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Image(String); impl TryFrom<&str> for Image { @@ -120,7 +143,7 @@ impl Image { /// assert_eq!(command1.as_str(), "mycommand"); /// assert_eq!(command2.as_str(), "myothercommand"); /// ``` -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Command(String); impl TryFrom<&str> for Command { @@ -190,6 +213,24 @@ impl From<&str> for AssetLocation { } } +impl Display for AssetLocation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AssetLocation::Url(value) => write!(f, "{}", value.as_str()), + AssetLocation::FilePath(value) => write!(f, "{}", value.display()), + } + } +} + +impl Serialize for AssetLocation { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + /// A CLI argument passed to an executed command, can be an option with an assigned value or a simple flag to enable/disable a feature. /// A flag arg can be constructed from a `&str` and a option arg can be constructed from a `(&str, &str)`. /// @@ -221,13 +262,27 @@ impl From<(&str, &str)> for Arg { } } +impl Serialize for Arg { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + match self { + Arg::Flag(value) => serializer.serialize_str(value), + Arg::Option(option, value) => { + serializer.serialize_str(&format!("{}={}", option, value)) + }, + } + } +} + #[derive(Debug, Default, Clone)] pub struct ValidationContext { pub used_ports: Vec<Port>, pub used_nodes_names: Vec<String>, } -#[derive(Default)] +#[derive(Default, Debug, Clone, PartialEq)] pub struct ChainDefaultContext { pub(crate) default_command: Option<Command>, pub(crate) default_image: Option<Image>,