From 5a429970454536ef024c16225f5d025e1998e151 Mon Sep 17 00:00:00 2001 From: Artemy Egorov Date: Mon, 5 Aug 2024 18:43:18 +0300 Subject: [PATCH] feat: convert to typed from daletl --- src/daletl.rs | 10 +- src/daletpack/encode.rs | 4 +- src/traits/from_daletl.rs | 195 +++++++++++++++++++++++++ src/traits/{typed.rs => from_typed.rs} | 24 +-- src/traits/is_null_daletl.rs | 19 +++ src/traits/mod.rs | 4 +- src/typed.rs | 7 +- tests/bench.rs | 5 +- 8 files changed, 239 insertions(+), 29 deletions(-) create mode 100644 src/traits/from_daletl.rs rename src/traits/{typed.rs => from_typed.rs} (90%) create mode 100644 src/traits/is_null_daletl.rs diff --git a/src/daletl.rs b/src/daletl.rs index a6b0b3b..42ae55b 100644 --- a/src/daletl.rs +++ b/src/daletl.rs @@ -3,7 +3,10 @@ use num_enum::TryFromPrimitive; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -pub type DlPage = Vec; +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +pub struct DlPage { + pub data: Vec, +} #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct DlTag { @@ -79,8 +82,3 @@ pub enum DlTid { pub trait IsNull { fn is_null(&self) -> bool; } - -pub trait ToDaletlPage { - /// Convert to daletl Page - fn to_dl_page(self) -> DlPage; -} diff --git a/src/daletpack/encode.rs b/src/daletpack/encode.rs index 844173b..4051214 100644 --- a/src/daletpack/encode.rs +++ b/src/daletpack/encode.rs @@ -8,13 +8,13 @@ pub fn encode(page: &DlPage) -> Result, DaletPackError> { } pub fn encode_no_compress(page: &DlPage) -> Result, DaletPackError> { - if page.len() > 2usize.pow(32) { + if page.data.len() > 2usize.pow(32) { return Err(DaletPackError::PageMaxSizeExceeded); } let mut bv: Vec = Vec::new(); - for tag in page { + for tag in &page.data { write_tag(&mut bv, tag)?; } diff --git a/src/traits/from_daletl.rs b/src/traits/from_daletl.rs new file mode 100644 index 0000000..6877d9e --- /dev/null +++ b/src/traits/from_daletl.rs @@ -0,0 +1,195 @@ +use crate::{ + daletl::*, + typed::{ + Tag::{self, *}, + *, + }, +}; + +impl TryFrom for Tag { + type Error = ConversionError; + + fn try_from(tag: DlTag) -> Result { + let result = match tag.id { + DlTid::El => El(tag.body.try_into()?), + DlTid::H => H(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::P => P(tag.body.try_into()?), + DlTid::Br => Br, + DlTid::Ul => Ul(tag.body.try_into()?), + DlTid::Ol => Ol(tag.body.try_into()?), + DlTid::Row => Row(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Link => Link(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Navlink => Navlink(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Btn => Btn(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Navbtn => Navbtn(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Img => Img(tag.argument.try_into()?), + DlTid::Table => Table(tag.body.try_into()?), + DlTid::Tcol => Tcol(tag.body.try_into()?), + DlTid::Tpcol => Tpcol(tag.body.try_into()?), + DlTid::Hr => Hr, + DlTid::B => B(tag.body.try_into()?), + DlTid::I => I(tag.body.try_into()?), + DlTid::Bq => Bq(tag.body.try_into()?), + DlTid::Footlnk => Footlnk(tag.argument.try_into()?), + DlTid::Footn => Footn(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::A => A(tag.argument.try_into()?), + DlTid::S => S(tag.body.try_into()?), + DlTid::Sup => Sup(tag.body.try_into()?), + DlTid::Sub => Sub(tag.body.try_into()?), + DlTid::Disc => Disc(tag.body.try_into()?), + DlTid::Bl => Bl(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Carousel => Carousel(tag.body.try_into()?), + DlTid::Code => Code(tag.body.try_into()?, tag.argument.try_into()?), + DlTid::Pre => Pre(tag.body.try_into()?), + }; + + Ok(result) + } +} + +impl TryFrom for Hl { + type Error = ConversionError; + + fn try_from(value: DlArgument) -> Result { + match value { + DlArgument::Number(n) => n.try_into().map_err(|_| ConversionError), + _ => Err(ConversionError), + } + } +} + +impl TryFrom for AlignArg { + type Error = ConversionError; + + fn try_from(value: DlArgument) -> Result { + match value { + DlArgument::Number(n) => n.try_into().map_err(|_| ConversionError), + _ => Err(ConversionError), + } + } +} + +impl TryFrom for TNArg { + type Error = ConversionError; + + fn try_from(value: DlArgument) -> Result { + match value { + DlArgument::Text(t) => Ok(TNArg::Text(t.into())), + DlArgument::Null => Ok(TNArg::Null), + _ => Err(ConversionError), + } + } +} + +impl TryFrom for Body { + type Error = ConversionError; + + fn try_from(value: DlBody) -> Result { + match value { + DlBody::Text(t) => Ok(t.into()), + DlBody::Tags(t) => Ok(Body::Tags( + t.into_iter() + .map(|dltag| dltag.try_into()) + .collect::, Self::Error>>()?, + )), + DlBody::Null => Ok(Body::Null), + } + } +} + +impl TryFrom for String { + type Error = ConversionError; + + fn try_from(value: DlBody) -> Result { + match value { + DlBody::Text(s) => Ok(s), + _ => Err(ConversionError), + } + } +} + +impl From for Arg { + fn from(value: DlArgument) -> Self { + match value { + DlArgument::Text(s) => s.into(), + DlArgument::Number(n) => n.into(), + DlArgument::Null => Self::Null, + } + } +} + +impl TryFrom for NNArg { + type Error = ConversionError; + + fn try_from(value: DlArgument) -> Result { + match value { + DlArgument::Text(t) => Ok(t.into()), + DlArgument::Number(n) => Ok(n.into()), + DlArgument::Null => Err(ConversionError), + } + } +} + +impl TryFrom for String { + type Error = ConversionError; + + fn try_from(value: DlArgument) -> Result { + match value { + DlArgument::Text(s) => Ok(s), + _ => Err(ConversionError), + } + } +} + +impl TryFrom for NNBody { + type Error = ConversionError; + + fn try_from(value: DlBody) -> Result { + match value { + DlBody::Text(t) => Ok(t.into()), + DlBody::Tags(t) => Ok(NNBody::Tags( + t.into_iter() + .map(|dltag| dltag.try_into()) + .collect::, Self::Error>>()?, + )), + DlBody::Null => Err(ConversionError), + } + } +} + +impl TryFrom for Vec { + type Error = ConversionError; + + fn try_from(value: DlBody) -> Result { + match value { + DlBody::Tags(t) => t.into_iter().map(|dltag| dltag.try_into()).collect(), + _ => Err(ConversionError), + } + } +} + +impl TryFrom for Vec { + type Error = ConversionError; + + fn try_from(value: DlPage) -> Result { + value + .data + .into_iter() + .map(|dltag| dltag.try_into()) + .collect() + } +} + +impl TryFrom for Page { + type Error = ConversionError; + + fn try_from(value: DlPage) -> Result { + Ok(Self { + data: value + .data + .into_iter() + .map(|dltag| dltag.try_into()) + .collect::, Self::Error>>()?, + }) + } +} diff --git a/src/traits/typed.rs b/src/traits/from_typed.rs similarity index 90% rename from src/traits/typed.rs rename to src/traits/from_typed.rs index 88ec21f..f152a9e 100644 --- a/src/traits/typed.rs +++ b/src/traits/from_typed.rs @@ -116,26 +116,18 @@ impl From> for DlBody { } } -impl ToDaletlPage for Page { - fn to_dl_page(self) -> DlPage { - self.into_iter().map(|tag| tag.into()).collect() - } -} - -impl IsNull for DlBody { - fn is_null(&self) -> bool { - match self { - Self::Null => true, - _ => false, +impl From> for DlPage { + fn from(value: Vec) -> Self { + Self { + data: value.into_iter().map(|t| t.into()).collect(), } } } -impl IsNull for DlArgument { - fn is_null(&self) -> bool { - match self { - Self::Null => true, - _ => false, +impl From for DlPage { + fn from(value: Page) -> Self { + Self { + data: value.data.into_iter().map(|t| t.into()).collect(), } } } diff --git a/src/traits/is_null_daletl.rs b/src/traits/is_null_daletl.rs new file mode 100644 index 0000000..3f33717 --- /dev/null +++ b/src/traits/is_null_daletl.rs @@ -0,0 +1,19 @@ +use crate::daletl::{DlArgument, DlBody, IsNull}; + +impl IsNull for DlBody { + fn is_null(&self) -> bool { + match self { + Self::Null => true, + _ => false, + } + } +} + +impl IsNull for DlArgument { + fn is_null(&self) -> bool { + match self { + Self::Null => true, + _ => false, + } + } +} diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 2f716a8..be81ebd 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -1 +1,3 @@ -mod typed; +mod from_daletl; +mod from_typed; +mod is_null_daletl; diff --git a/src/typed.rs b/src/typed.rs index 6c30c94..ffd5b38 100644 --- a/src/typed.rs +++ b/src/typed.rs @@ -1,7 +1,12 @@ use enum_procs::AutoFrom; use num_enum::TryFromPrimitive; -pub type Page = Vec; +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Page { + pub data: Vec, +} + +pub struct ConversionError; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Tag { diff --git a/tests/bench.rs b/tests/bench.rs index c25a9f4..6b06ece 100644 --- a/tests/bench.rs +++ b/tests/bench.rs @@ -1,5 +1,4 @@ use dalet::{ - daletl::ToDaletlPage, daletpack::*, typed::{Hl, Page, TNArg, Tag::*}, }; @@ -32,7 +31,7 @@ pub fn compress_zlib(data: &Vec) -> std::io::Result> { #[test] fn bench() { - let page: Page = vec![ + let page = vec![ H("I am heading".into(), Hl::One), H("Heading 2".into(), Hl::Two), P(vec![ @@ -78,7 +77,7 @@ fn bench() { ]), ]; - let dalet_page = page.to_dl_page(); + let dalet_page = page.into(); let markdown = iprint!("Markdown", include_str!("./bench.md").as_bytes().to_vec()); let daletpack = iprint!("Daletpack", encode_no_compress(&dalet_page).unwrap());