use std::str::FromStr;
use crate::enc::BinWriter;
use crate::encoding::Encoding;
use crate::encoding::HasEncoding;
use crate::has_encoding;
use crate::nom::NomReader;
use hex::FromHexError;
use num_bigint::Sign;
use serde::{Deserialize, Serialize};
#[cfg(feature = "fuzzing")]
use crate::fuzzing::bigint::BigIntMutator;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BigInt(pub num_bigint::BigInt);
impl From<num_bigint::BigInt> for BigInt {
fn from(from: num_bigint::BigInt) -> Self {
BigInt(from)
}
}
impl From<BigInt> for num_bigint::BigInt {
fn from(from: BigInt) -> Self {
from.0
}
}
impl From<&num_bigint::BigInt> for BigInt {
fn from(from: &num_bigint::BigInt) -> Self {
BigInt(from.clone())
}
}
impl From<&BigInt> for num_bigint::BigInt {
fn from(from: &BigInt) -> Self {
from.0.clone()
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Zarith(pub num_bigint::BigInt);
impl From<num_bigint::BigInt> for Zarith {
fn from(from: num_bigint::BigInt) -> Self {
Zarith(from)
}
}
impl From<Zarith> for num_bigint::BigInt {
fn from(from: Zarith) -> Self {
from.0
}
}
impl From<&num_bigint::BigInt> for Zarith {
fn from(from: &num_bigint::BigInt) -> Self {
Zarith(from.clone())
}
}
impl From<&Zarith> for num_bigint::BigInt {
fn from(from: &Zarith) -> Self {
from.0.clone()
}
}
impl From<Zarith> for BigInt {
fn from(source: Zarith) -> Self {
Self(source.0)
}
}
impl From<&Zarith> for BigInt {
fn from(source: &Zarith) -> Self {
Self(source.0.clone())
}
}
has_encoding!(Zarith, ZARITH_ENCODING, { Encoding::Z });
#[cfg_attr(feature = "fuzzing", derive(fuzzcheck::DefaultMutator))]
#[derive(Clone, Debug)]
pub struct Mumav(
#[cfg_attr(feature = "fuzzing", field_mutator(BigIntMutator))] pub num_bigint::BigInt,
);
impl<'de> Deserialize<'de> for Mumav {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
let string: String = serde::Deserialize::deserialize(deserializer)?;
let big_int: num_bigint::BigInt = string
.parse()
.map_err(|err| serde::de::Error::custom(format!("cannot parse big int: {err}")))?;
if big_int.sign() == Sign::Minus {
return Err(serde::de::Error::custom("negative number for natural"));
}
Ok(Self(big_int))
} else {
Ok(Self(serde::Deserialize::deserialize(deserializer)?))
}
}
}
impl Serialize for Mumav {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
let string = self.0.to_string();
string.serialize(serializer)
} else {
self.0.serialize(serializer)
}
}
}
impl From<num_bigint::BigInt> for Mumav {
fn from(from: num_bigint::BigInt) -> Self {
Mumav(from)
}
}
impl From<Mumav> for num_bigint::BigInt {
fn from(from: Mumav) -> Self {
from.0
}
}
impl From<&num_bigint::BigInt> for Mumav {
fn from(from: &num_bigint::BigInt) -> Self {
Mumav(from.clone())
}
}
impl From<&Mumav> for num_bigint::BigInt {
fn from(from: &Mumav) -> Self {
from.0.clone()
}
}
impl From<Mumav> for BigInt {
fn from(source: Mumav) -> Self {
Self(source.0)
}
}
impl From<&Mumav> for BigInt {
fn from(source: &Mumav) -> Self {
Self(source.0.clone())
}
}
has_encoding!(Mumav, MUMAV_ENCODING, { Encoding::Mumav });
#[derive(Clone, PartialEq, Eq)]
pub struct SizedBytes<const SIZE: usize>(pub [u8; SIZE]);
impl<const SIZE: usize> std::fmt::Display for SizedBytes<SIZE> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", hex::encode(self.0))
}
}
impl<const SIZE: usize> std::fmt::Debug for SizedBytes<SIZE> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "bytes: {}", hex::encode(self.0))
}
}
impl<const SIZE: usize> AsRef<[u8]> for SizedBytes<SIZE> {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl<const SIZE: usize> AsMut<[u8]> for SizedBytes<SIZE> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl<const SIZE: usize> From<[u8; SIZE]> for SizedBytes<SIZE> {
fn from(bytes: [u8; SIZE]) -> Self {
Self(bytes)
}
}
impl<const SIZE: usize> From<SizedBytes<SIZE>> for [u8; SIZE] {
fn from(bytes: SizedBytes<SIZE>) -> Self {
bytes.0
}
}
impl<const SIZE: usize> Serialize for SizedBytes<SIZE> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_str(&hex::encode(self.0.as_ref()))
} else {
serializer.serialize_newtype_struct(stringify!(Bytes<SIZE>), self.0.as_ref())
}
}
}
struct BytesVisitor<const SIZE: usize>;
impl<'de, const SIZE: usize> serde::de::Visitor<'de> for BytesVisitor<SIZE> {
type Value = SizedBytes<{ SIZE }>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("eigher sequence of bytes or hex encoded data expected")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let mut bytes = [0_u8; SIZE];
hex::decode_to_slice(v, &mut bytes)
.map_err(|e| E::custom(format!("error constructing bytes from hex: {e}")))?;
Ok(bytes.into())
}
fn visit_newtype_struct<E>(self, e: E) -> Result<Self::Value, E::Error>
where
E: serde::Deserializer<'de>,
{
let mut bytes = [0_u8; SIZE];
match <Vec<u8> as serde::Deserialize>::deserialize(e) {
Ok(val) if val.len() == SIZE => bytes.copy_from_slice(&val),
Ok(val) => {
return Err(serde::de::Error::custom(format!(
"invalid lenght, expected {SIZE}, got {len}",
len = val.len()
)))
}
Err(err) => {
return Err(err);
}
};
Ok(bytes.into())
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut bytes = [0_u8; SIZE];
match seq.next_element::<Vec<u8>>() {
Ok(Some(val)) if val.len() == SIZE => bytes.copy_from_slice(&val),
Ok(Some(val)) => {
return Err(serde::de::Error::custom(format!(
"invalid lenght, expected {SIZE}, got {len}",
len = val.len()
)))
}
Ok(None) => return Err(serde::de::Error::custom("no bytes".to_string())),
Err(err) => return Err(err),
};
Ok(bytes.into())
}
}
impl<'de, const SIZE: usize> Deserialize<'de> for SizedBytes<SIZE> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
if deserializer.is_human_readable() {
deserializer.deserialize_str(BytesVisitor)
} else {
deserializer.deserialize_newtype_struct("Bytes<SIZE>", BytesVisitor)
}
}
}
impl<'a, const SIZE: usize> NomReader<'a> for SizedBytes<SIZE> {
fn nom_read(input: &[u8]) -> crate::nom::NomResult<Self> {
use crate::nom;
let (input, slice) = nom::sized(SIZE, nom::bytes)(input)?;
let mut bytes = [0; SIZE];
bytes.copy_from_slice(&slice);
Ok((input, bytes.into()))
}
}
impl<const SIZE: usize> BinWriter for SizedBytes<SIZE> {
fn bin_write(&self, bytes: &mut Vec<u8>) -> crate::enc::BinResult {
use crate::enc;
enc::put_bytes(&self.0, bytes);
Ok(())
}
}
impl<const SIZE: usize> HasEncoding for SizedBytes<SIZE> {
fn encoding() -> Encoding {
Encoding::sized(SIZE, Encoding::Bytes)
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
#[cfg_attr(feature = "fuzzing", derive(fuzzcheck::DefaultMutator))]
pub struct Bytes(Vec<u8>);
#[derive(Debug, thiserror::Error)]
pub enum BytesDecodeError {
#[error(transparent)]
Hex(#[from] FromHexError),
}
impl Bytes {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl std::fmt::Debug for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Bytes").field(&self.to_string()).finish()
}
}
impl std::fmt::Display for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
hex::encode(&self.0).fmt(f)
}
}
impl From<Vec<u8>> for Bytes {
fn from(source: Vec<u8>) -> Self {
Self(source)
}
}
impl From<Bytes> for Vec<u8> {
fn from(source: Bytes) -> Self {
source.0
}
}
impl FromStr for Bytes {
type Err = BytesDecodeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(hex::decode(s)?))
}
}
impl AsRef<[u8]> for Bytes {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl AsRef<Vec<u8>> for Bytes {
fn as_ref(&self) -> &Vec<u8> {
&self.0
}
}
impl HasEncoding for Bytes {
fn encoding() -> Encoding {
Encoding::list(Encoding::Uint8)
}
}
impl<'a> NomReader<'a> for Bytes {
fn nom_read(input: &[u8]) -> crate::nom::NomResult<Self> {
use crate::nom::bytes;
let (input, b) = bytes(input)?;
Ok((input, Self(b)))
}
}
impl BinWriter for Bytes {
fn bin_write(&self, output: &mut Vec<u8>) -> crate::enc::BinResult {
crate::enc::put_bytes(self.0.as_ref(), output);
Ok(())
}
}
impl serde::Serialize for Bytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
let hex_bytes = hex::encode(&self.0);
serde::Serialize::serialize(&hex_bytes, serializer)
} else {
serde::Serialize::serialize(&self.0, serializer)
}
}
}
impl<'de> serde::Deserialize<'de> for Bytes {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
let hex_bytes: String = serde::Deserialize::deserialize(deserializer)?;
let bytes = hex::decode(&hex_bytes).map_err(|err| {
serde::de::Error::custom(format!("error decoding from hex string: {err}"))
})?;
Ok(Self(bytes))
} else {
let bytes = serde::Deserialize::deserialize(deserializer)?;
Ok(Self(bytes))
}
}
}
pub const BYTE_VAL_TRUE: u8 = 0xFF;
pub const BYTE_VAL_FALSE: u8 = 0;
pub const BYTE_VAL_SOME: u8 = 1;
pub const BYTE_VAL_NONE: u8 = 0;
pub const BYTE_FIELD_SOME: u8 = 0xFF;
pub const BYTE_FIELD_NONE: u8 = 0;
#[derive(PartialEq, Debug)]
pub enum Value {
Unit,
Int8(i8),
Uint8(u8),
Int16(i16),
Uint16(u16),
Int31(i32),
Int32(i32),
Int64(i64),
RangedInt(i32),
Float(f64),
RangedFloat(f64),
Bool(bool),
String(String),
Bytes(Vec<u8>),
Option(Option<Box<Value>>),
List(Vec<Value>),
Enum(Option<String>, Option<u32>),
Tag(String, Box<Value>),
Record(Vec<(String, Value)>),
Tuple(Vec<Value>),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bytes_to_string() {
let bytes = Bytes(vec![0xde, 0xad, 0xbe, 0xef]);
let bytes_hex = bytes.to_string();
assert_eq!(&bytes_hex, "deadbeef");
}
#[test]
fn bytes_parse() {
let bytes: Bytes = "deadbeef".parse().unwrap();
assert_eq!(bytes, Bytes(vec![0xde, 0xad, 0xbe, 0xef]));
}
#[test]
fn bytes_parse_error() {
let _ = "deadbeefe".parse::<Bytes>().expect_err("");
let _ = "morebeef".parse::<Bytes>().expect_err("");
}
#[test]
fn bytes_to_json() {
let bytes = Bytes(vec![0xde, 0xad, 0xbe, 0xef]);
let json = serde_json::to_value(bytes).unwrap();
assert!(matches!(json.as_str(), Some("deadbeef")))
}
#[test]
fn bytes_from_json() {
let json = serde_json::json!("deadbeef");
let bytes: Bytes = serde_json::from_value(json).unwrap();
assert_eq!(bytes, Bytes(vec![0xde, 0xad, 0xbe, 0xef]));
}
}