Skip to content

Commit

Permalink
Update JSON Schemas
Browse files Browse the repository at this point in the history
Int / Ipv4 / Ipv6 / ByronAddress manually implemented
Misc byte wrappers now use hex bytestring included in cddl-codegen
update.
All wrappers via said cddl-codegne update now exclude the `{ inner: T }`
in favor of just `T` directly. e.g. DnsName / Url even when not bytes
  • Loading branch information
rooooooooob authored and gostkin committed Jan 30, 2024
1 parent fda2228 commit 2227ab6
Show file tree
Hide file tree
Showing 10 changed files with 508 additions and 45 deletions.
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

0 comments on commit 2227ab6

Please sign in to comment.