Skip to content

Commit

Permalink
Merge pull request #21 from strict-types/ascii-char
Browse files Browse the repository at this point in the history
Remove register_ascii API
  • Loading branch information
dr-orlovsky committed Jun 28, 2023
2 parents 28e2f91 + b75e490 commit 1b49ee7
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "strict_encoding"
version = "2.3.0"
version = "2.3.1"
description = "Strict encoding: deterministic & confined binary serialization for strict types"
keywords = ["strict-types", "gadt", "serialization", "serde", "protobuf"]
categories = ["encoding", "parsing"]
Expand Down
6 changes: 5 additions & 1 deletion rust/src/embedded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use amplify::num::{i1024, i256, i512, u1024, u24, u256, u512};
use amplify::{Array, Wrapper};

use crate::constants::*;
use crate::stl::AsciiSym;
use crate::{
DecodeError, DefineUnion, ReadTuple, ReadUnion, Sizing, StrictDecode, StrictDumb, StrictEncode,
StrictProduct, StrictStruct, StrictSum, StrictTuple, StrictType, StrictUnion, TypeName,
Expand Down Expand Up @@ -365,7 +366,10 @@ impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictEncode
fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
unsafe {
writer
.register_ascii(Sizing::new(MIN_LEN as u64, MAX_LEN as u64))
.register_list(
&AsciiSym::strict_dumb(),
Sizing::new(MIN_LEN as u64, MAX_LEN as u64),
)
.write_string::<MAX_LEN>(self.as_bytes())
}
}
Expand Down
40 changes: 37 additions & 3 deletions rust/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ use std::fmt::{self, Debug, Formatter};
use std::str::FromStr;

use amplify::ascii::{AsAsciiStrError, AsciiChar, AsciiString, FromAsciiError};
use amplify::confinement::Confined;
use amplify::confinement::{Confined, NonEmptyVec};
use amplify::{confinement, Wrapper};

use crate::{impl_strict_newtype, STRICT_TYPES_LIB};
use crate::stl::AlphaNumLodash;
use crate::{
impl_strict_newtype, DecodeError, ReadTuple, StrictDecode, StrictDumb, StrictEncode,
StrictProduct, StrictTuple, StrictType, TypedRead, TypedWrite, STRICT_TYPES_LIB,
};

#[derive(Clone, Eq, PartialEq, Hash, Debug, Display, Error, From)]
#[display(doc_comments)]
Expand Down Expand Up @@ -116,7 +120,33 @@ impl Debug for Ident {
}
}

impl_strict_newtype!(Ident, STRICT_TYPES_LIB, "Dumb");
impl StrictDumb for Ident {
fn strict_dumb() -> Self { Self::from("Dumb") }
}
impl StrictType for Ident {
const STRICT_LIB_NAME: &'static str = STRICT_TYPES_LIB;
}
impl StrictProduct for Ident {}
impl StrictTuple for Ident {
const FIELD_COUNT: u8 = 1;
}
impl StrictEncode for Ident {
fn strict_encode<W: TypedWrite>(&self, writer: W) -> std::io::Result<W> {
let iter = self
.0
.as_bytes()
.iter()
.map(|c| AlphaNumLodash::try_from(*c).unwrap());
writer.write_newtype::<Self>(
&NonEmptyVec::<AlphaNumLodash, 100>::try_from_iter(iter).unwrap(),
)
}
}
impl StrictDecode for Ident {
fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
reader.read_tuple(|r| Ok(Self(r.read_field()?)))
}
}

#[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)]
#[wrapper(Deref, Display, FromStr)]
Expand Down Expand Up @@ -172,6 +202,10 @@ impl Debug for FieldName {
}
}

impl FieldName {
pub fn as_str(&self) -> &str { self.0.as_str() }
}

impl_strict_newtype!(FieldName, STRICT_TYPES_LIB);

pub type VariantName = FieldName;
Expand Down
173 changes: 173 additions & 0 deletions rust/src/stl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,179 @@ impl StrictDecode for u4 {
}
}

#[derive(Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)]
#[wrapper(Deref, Display, Debug)]
#[wrapper_mut(DerefMut)]
#[derive(StrictDumb)]
#[strict_type(lib = LIB_NAME_STD, dumb = Self(AsciiChar::A), crate = crate)]
pub struct AsciiSym(AsciiChar);

impl From<AsciiSym> for u8 {
fn from(value: AsciiSym) -> Self { value.0.as_byte() }
}

impl TryFrom<u8> for AsciiSym {
type Error = VariantError<u8>;

fn try_from(value: u8) -> Result<Self, Self::Error> {
AsciiChar::from_ascii(value)
.map_err(|_| VariantError(AsciiSym::strict_name(), value))
.map(Self)
}
}
impl StrictType for AsciiSym {
const STRICT_LIB_NAME: &'static str = LIB_NAME_STD;
fn strict_name() -> Option<TypeName> { Some(tn!("Ascii")) }
}
impl StrictSum for AsciiSym {
const ALL_VARIANTS: &'static [(u8, &'static str)] = &[
(b'\0', "nul"),
(0x01, "soh"),
(0x02, "stx"),
(0x03, "etx"),
(0x04, "eot"),
(0x05, "enq"),
(0x06, "ack"),
(0x07, "bel"),
(0x08, "bs"),
(b'\t', "ht"),
(b'\n', "lf"),
(0x0b, "vt"),
(0x0c, "ff"),
(b'\r', "cr"),
(0x0e, "so"),
(0x0f, "si"),
(0x10, "dle"),
(0x11, "dc1"),
(0x12, "dc2"),
(0x13, "dc3"),
(0x14, "dc4"),
(0x15, "nack"),
(0x16, "syn"),
(0x17, "etb"),
(0x18, "can"),
(0x19, "em"),
(0x1a, "sub"),
(0x1b, "esc"),
(0x1c, "fs"),
(0x1d, "gs"),
(0x1e, "rs"),
(0x1f, "us"),
(b' ', "space"),
(b'!', "excl"),
(b'"', "quotes"),
(b'#', "hash"),
(b'$', "dollar"),
(b'%', "percent"),
(b'&', "ampersand"),
(b'\'', "apostrophe"),
(b'(', "bracketL"),
(b')', "bracketR"),
(b'*', "asterisk"),
(b'+', "plus"),
(b',', "comma"),
(b'-', "minus"),
(b'.', "dot"),
(b'/', "slash"),
(b'0', "zero"),
(b'1', "one"),
(b'2', "two"),
(b'3', "three"),
(b'4', "four"),
(b'5', "five"),
(b'6', "six"),
(b'7', "seven"),
(b'8', "eight"),
(b'9', "nine"),
(b':', "colon"),
(b';', "semiColon"),
(b'<', "less"),
(b'=', "equal"),
(b'>', "greater"),
(b'?', "question"),
(b'@', "at"),
(b'A', "A"),
(b'B', "B"),
(b'C', "C"),
(b'D', "D"),
(b'E', "E"),
(b'F', "F"),
(b'G', "G"),
(b'H', "H"),
(b'I', "I"),
(b'J', "J"),
(b'K', "K"),
(b'L', "L"),
(b'M', "M"),
(b'N', "N"),
(b'O', "O"),
(b'P', "P"),
(b'Q', "Q"),
(b'R', "R"),
(b'S', "S"),
(b'T', "T"),
(b'U', "U"),
(b'V', "V"),
(b'W', "W"),
(b'X', "X"),
(b'Y', "Y"),
(b'Z', "Z"),
(b'[', "sqBracketL"),
(b'\\', "backSlash"),
(b']', "sqBracketR"),
(b'^', "caret"),
(b'_', "lodash"),
(b'`', "backtick"),
(b'a', "a"),
(b'b', "b"),
(b'c', "c"),
(b'd', "d"),
(b'e', "e"),
(b'f', "f"),
(b'g', "g"),
(b'h', "h"),
(b'i', "i"),
(b'j', "j"),
(b'k', "k"),
(b'l', "l"),
(b'm', "m"),
(b'n', "n"),
(b'o', "o"),
(b'p', "p"),
(b'q', "q"),
(b'r', "r"),
(b's', "s"),
(b't', "t"),
(b'u', "u"),
(b'v', "v"),
(b'w', "w"),
(b'x', "x"),
(b'y', "y"),
(b'z', "z"),
(b'{', "cBracketL"),
(b'|', "pipe"),
(b'}', "cBracketR"),
(b'~', "tilde"),
(0x7f, "del"),
];
fn variant_name(&self) -> &'static str {
Self::ALL_VARIANTS
.into_iter()
.find(|(s, _)| *s == self.as_byte())
.map(|(_, v)| *v)
.expect("missed ASCII character variant")
}
}
impl StrictEnum for AsciiSym {}
impl StrictEncode for AsciiSym {
fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> { writer.write_enum(*self) }
}
impl StrictDecode for AsciiSym {
fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
reader.read_enum()
}
}

#[derive(Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)]
#[wrapper(Deref, Display, Debug)]
#[wrapper_mut(DerefMut)]
Expand Down
5 changes: 4 additions & 1 deletion rust/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ pub trait TypedWrite: Sized {
#[doc(hidden)]
unsafe fn register_unicode(self, sizing: Sizing) -> Self { self }
#[doc(hidden)]
unsafe fn register_ascii(self, sizing: Sizing) -> Self { self }
#[deprecated(since = "2.3.1", note = "use register_list with AsciiSym type")]
unsafe fn register_ascii(self, sizing: Sizing) -> Self {
panic!("TypedWrite::register_ascii must not be called; pls see compilation warnings")
}
#[doc(hidden)]
unsafe fn register_list(self, ty: &impl StrictEncode, sizing: Sizing) -> Self { self }
#[doc(hidden)]
Expand Down
2 changes: 2 additions & 0 deletions rust/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use std::io;

use crate::{ReadStruct, VariantName, WriteStruct, STRICT_TYPES_LIB};

// TODO: Control that min > max!
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))]
pub struct Sizing {
Expand All @@ -34,6 +35,7 @@ pub struct Sizing {
impl_strict_struct!(Sizing, STRICT_TYPES_LIB; min, max);

impl Sizing {
// TODO: Remove (in strict-types use Array with size 1 for char types instead).
pub const ONE: Sizing = Sizing { min: 1, max: 1 };

pub const U8: Sizing = Sizing {
Expand Down

0 comments on commit 1b49ee7

Please sign in to comment.