Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update JSON Schemas #300

Merged
merged 1 commit into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions chain/rust/src/assets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ use cml_core::error::*;

use std::convert::TryFrom;

#[derive(
Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema, derivative::Derivative,
)]
#[derive(Clone, Debug, derivative::Derivative)]
#[derivative(Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct AssetName {
pub inner: Vec<u8>,
Expand All @@ -24,7 +22,6 @@ pub struct AssetName {
PartialOrd = "ignore",
Hash = "ignore"
)]
#[serde(skip)]
pub encodings: Option<AssetNameEncoding>,
}

Expand Down Expand Up @@ -64,3 +61,44 @@ impl From<AssetName> for Vec<u8> {
wrapper.inner
}
}

impl serde::Serialize for AssetName {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&hex::encode(self.inner.clone()))
}
}

impl<'de> serde::de::Deserialize<'de> for AssetName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
hex::decode(&s)
.ok()
.and_then(|bytes| AssetName::new(bytes).ok())
.ok_or_else(|| {
serde::de::Error::invalid_value(
serde::de::Unexpected::Str(&s),
&"invalid hex bytes",
)
})
}
}

impl schemars::JsonSchema for AssetName {
fn schema_name() -> String {
String::from("AssetName")
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
String::json_schema(gen)
}

fn is_referenceable() -> bool {
String::is_referenceable()
}
}
13 changes: 1 addition & 12 deletions chain/rust/src/byron/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,7 @@ impl AddressContent {
}
}

#[derive(
Clone,
Debug,
Eq,
PartialEq,
Ord,
PartialOrd,
Hash,
serde::Deserialize,
serde::Serialize,
schemars::JsonSchema,
)]
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ByronAddress {
pub content: AddressContent,
pub crc: Crc32,
Expand Down
36 changes: 36 additions & 0 deletions chain/rust/src/byron/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,42 @@ pub fn make_icarus_bootstrap_witness(
BootstrapWitness::new(vkey, signature, chain_code, addr.content.addr_attributes).unwrap()
}

impl serde::Serialize for ByronAddress {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_base58())
}
}

impl<'de> serde::de::Deserialize<'de> for ByronAddress {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let base58 = <String as serde::de::Deserialize>::deserialize(deserializer)?;
Self::from_base58(&base58).map_err(|_e| {
serde::de::Error::invalid_value(
serde::de::Unexpected::Str(&base58),
&"base58 byron address string",
)
})
}
}

impl schemars::JsonSchema for ByronAddress {
fn schema_name() -> String {
String::from("ByronAddress")
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
String::json_schema(gen)
}
fn is_referenceable() -> bool {
String::is_referenceable()
}
}

#[cfg(test)]
mod tests {
use super::ByronAddress;
Expand Down
82 changes: 74 additions & 8 deletions chain/rust/src/certs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,9 @@ impl DRep {
}
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[derive(Clone, Debug)]
pub struct DnsName {
pub inner: String,
#[serde(skip)]
pub encodings: Option<DnsNameEncoding>,
}

Expand Down Expand Up @@ -370,12 +369,46 @@ impl TryFrom<String> for DnsName {
}
}

impl serde::Serialize for DnsName {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.inner.serialize(serializer)
}
}

impl<'de> serde::de::Deserialize<'de> for DnsName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let inner = <String as serde::de::Deserialize>::deserialize(deserializer)?;
Self::new(inner.clone()).map_err(|_e| {
serde::de::Error::invalid_value(serde::de::Unexpected::Str(&inner), &"invalid DnsName")
})
}
}

impl schemars::JsonSchema for DnsName {
fn schema_name() -> String {
String::from("DnsName")
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
String::json_schema(gen)
}

fn is_referenceable() -> bool {
String::is_referenceable()
}
}

pub type DrepCredential = Credential;

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[derive(Clone, Debug)]
pub struct Ipv4 {
pub inner: Vec<u8>,
#[serde(skip)]
pub encodings: Option<Ipv4Encoding>,
}

Expand Down Expand Up @@ -416,10 +449,9 @@ impl From<Ipv4> for Vec<u8> {
}
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[derive(Clone, Debug)]
pub struct Ipv6 {
pub inner: Vec<u8>,
#[serde(skip)]
pub encodings: Option<Ipv6Encoding>,
}

Expand Down Expand Up @@ -873,10 +905,9 @@ impl UpdateDrepCert {
}
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[derive(Clone, Debug)]
pub struct Url {
pub inner: String,
#[serde(skip)]
pub encodings: Option<UrlEncoding>,
}

Expand Down Expand Up @@ -911,6 +942,41 @@ impl TryFrom<String> for Url {
}
}

impl serde::Serialize for Url {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.inner.serialize(serializer)
}
}

impl<'de> serde::de::Deserialize<'de> for Url {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let inner = <String as serde::de::Deserialize>::deserialize(deserializer)?;
Self::new(inner.clone()).map_err(|_e| {
serde::de::Error::invalid_value(serde::de::Unexpected::Str(&inner), &"invalid Url")
})
}
}

impl schemars::JsonSchema for Url {
fn schema_name() -> String {
String::from("Url")
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
String::json_schema(gen)
}

fn is_referenceable() -> bool {
String::is_referenceable()
}
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
pub struct VoteDelegCert {
pub stake_credential: StakeCredential,
Expand Down
135 changes: 134 additions & 1 deletion chain/rust/src/certs/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use super::StakeCredential;
use std::str::FromStr;

use super::{Ipv4, Ipv6, StakeCredential};
use cml_core::DeserializeError;
use cml_crypto::RawBytesEncoding;

impl StakeCredential {
Expand All @@ -10,3 +13,133 @@ impl StakeCredential {
}
}
}

#[derive(Debug, thiserror::Error)]
pub enum IPStringParsingError {
#[error("Invalid IP Address String, expected period-separated bytes e.g. 0.0.0.0")]
StringFormat,
#[error("Deserializing from bytes: {0:?}")]
DeserializeError(DeserializeError),
}

impl std::fmt::Display for Ipv4 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.inner
.iter()
.map(ToString::to_string)
.collect::<Vec<String>>()
.join(".")
)
}
}

impl FromStr for Ipv4 {
type Err = IPStringParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
s.split('.')
.map(FromStr::from_str)
.collect::<Result<Vec<u8>, _>>()
.map_err(|_e| IPStringParsingError::StringFormat)
.and_then(|bytes| Self::new(bytes).map_err(IPStringParsingError::DeserializeError))
}
}

impl serde::Serialize for Ipv4 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl<'de> serde::de::Deserialize<'de> for Ipv4 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
Self::from_str(&s).map_err(|_e| {
serde::de::Error::invalid_value(serde::de::Unexpected::Str(&s), &"invalid ipv4 address")
})
}
}

impl schemars::JsonSchema for Ipv4 {
fn schema_name() -> String {
String::from("Ipv4")
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
String::json_schema(gen)
}

fn is_referenceable() -> bool {
String::is_referenceable()
}
}

impl std::fmt::Display for Ipv6 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.inner
.iter()
.map(ToString::to_string)
.collect::<Vec<String>>()
.join(".")
)
}
}

impl FromStr for Ipv6 {
type Err = IPStringParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
s.split('.')
.map(FromStr::from_str)
.collect::<Result<Vec<u8>, _>>()
.map_err(|_e| IPStringParsingError::StringFormat)
.and_then(|bytes| Self::new(bytes).map_err(IPStringParsingError::DeserializeError))
}
}

impl serde::Serialize for Ipv6 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl<'de> serde::de::Deserialize<'de> for Ipv6 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
Self::from_str(&s).map_err(|_e| {
serde::de::Error::invalid_value(serde::de::Unexpected::Str(&s), &"invalid ipv6 address")
})
}
}

impl schemars::JsonSchema for Ipv6 {
fn schema_name() -> String {
String::from("Ipv6")
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
String::json_schema(gen)
}

fn is_referenceable() -> bool {
String::is_referenceable()
}
}
Loading
Loading