This commit is contained in:
Artemy Egorov 2024-08-02 17:49:52 +03:00
parent 5eb9e2abb6
commit 2737a066f5
14 changed files with 1202 additions and 21 deletions

23
.gitignore vendored
View file

@ -1,21 +1,2 @@
# Generated by Cargo /target
# will have compiled files and executables test.daletpack
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
# RustRover
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

516
Cargo.lock generated Normal file
View file

@ -0,0 +1,516 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "autocfg"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
dependencies = [
"jobserver",
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "dalet"
version = "1.0.0-pre4"
dependencies = [
"bincode",
"clap",
"flate2",
"num_enum",
"rmp-serde",
"serde",
"serde_repr",
"zstd",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "flate2"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indexmap"
version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jobserver"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "num_enum"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179"
dependencies = [
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "proc-macro-crate"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rmp"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
dependencies = [
"byteorder",
"num-traits",
"paste",
]
[[package]]
name = "rmp-serde"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
dependencies = [
"byteorder",
"rmp",
"serde",
]
[[package]]
name = "serde"
version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_repr"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
[[package]]
name = "toml_edit"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
dependencies = [
"memchr",
]
[[package]]
name = "zstd"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "7.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa556e971e7b568dc775c136fc9de8c779b1c2fc3a63defaafadffdbd3181afa"
dependencies = [
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.12+zstd.1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13"
dependencies = [
"cc",
"pkg-config",
]

30
Cargo.toml Normal file
View file

@ -0,0 +1,30 @@
[package]
name = "dalet"
version = "1.0.0-pre4"
edition = "2021"
authors = ["artegoser"]
license = "MIT"
description = "Dalet implementation in Rust"
repository = "https://github.com/txtdot/dalet"
homepage = "https://github.com/TxtDot/dalet/tree/main/libs/rust"
readme = "./README.md"
keywords = ["dalet"]
categories = ["compression", "compilers", "encoding"]
[dependencies]
clap = { version = "4.5.13", features = ["derive"] }
num_enum = "0.7.3"
serde = { version = "1.0", features = ["derive"] }
serde_repr = "0.1"
zstd = "0.13.2"
[dev-dependencies]
rmp-serde = { version = "1.3.0" }
bincode = { version = "1.3.3" }
flate2 = "1.0"
[features]
default = ["types", "daletpack"]
types = []
daletpack = ["types"]

257
src/abstractions.rs Normal file
View file

@ -0,0 +1,257 @@
use num_enum::TryFromPrimitive;
use crate::daletl::{self, t_new, Tid};
const NB: daletl::Body = daletl::Body::Null;
const NA: daletl::Argument = daletl::Argument::Null;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Tag {
El(NotNullBody),
H(String, HeadingLevel),
P(NotNullBody),
Br,
Ul(Vec<Tag>),
Ol(Vec<Tag>),
Row(Vec<Tag>, AlignArgument),
Link(Body, String),
Navlink(Body, String),
Btn(Body, String),
Navbtn(Body, String),
Img(String),
Table(Vec<Tag>),
Tcol(Vec<Tag>),
Tpcol(Vec<Tag>),
Hr,
B(String),
I(String),
Bq(NotNullBody),
Footlnk(TextOrNumberArgument),
Footn(String, TextOrNumberArgument),
A(TextOrNumberArgument),
S(String),
Sup(String),
Sub(String),
Disc(NotNullBody),
Bl(NotNullBody, AlignArgument),
Carousel(Vec<Tag>),
Code(String, TextOrNullArgument),
}
pub trait ToDaletl {
fn to_daletl(self) -> Vec<daletl::Tag>;
}
pub trait ToDaletlTag {
fn to_daletl_tag(self) -> daletl::Tag;
}
impl ToDaletlTag for Tag {
fn to_daletl_tag(self) -> daletl::Tag {
match self {
Tag::El(b) => t_new(Tid::El, b.to_daletl_body(), NA),
Tag::H(b, a) => t_new(Tid::H, b.to_daletl_body(), a.to_daletl_argument()),
Tag::P(b) => t_new(Tid::P, b.to_daletl_body(), NA),
Tag::Br => t_new(Tid::Br, NB, NA),
Tag::Ul(b) => t_new(Tid::Ul, b.to_daletl_body(), NA),
Tag::Ol(b) => t_new(Tid::Ol, b.to_daletl_body(), NA),
Tag::Row(b, a) => t_new(Tid::Row, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Link(b, a) => t_new(Tid::Link, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Navlink(b, a) => t_new(Tid::Navlink, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Btn(b, a) => t_new(Tid::Btn, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Navbtn(b, a) => t_new(Tid::Navbtn, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Img(a) => t_new(Tid::Img, NB, a.to_daletl_argument()),
Tag::Table(b) => t_new(Tid::Table, b.to_daletl_body(), NA),
Tag::Tcol(b) => t_new(Tid::Tcol, b.to_daletl_body(), NA),
Tag::Tpcol(b) => t_new(Tid::Tpcol, b.to_daletl_body(), NA),
Tag::Hr => t_new(Tid::Hr, NB, NA),
Tag::B(b) => t_new(Tid::B, b.to_daletl_body(), NA),
Tag::I(b) => t_new(Tid::I, b.to_daletl_body(), NA),
Tag::Bq(b) => t_new(Tid::Bq, b.to_daletl_body(), NA),
Tag::Footlnk(a) => t_new(Tid::Footlnk, NB, a.to_daletl_argument()),
Tag::Footn(b, a) => t_new(Tid::Footn, b.to_daletl_body(), a.to_daletl_argument()),
Tag::A(a) => t_new(Tid::A, NB, a.to_daletl_argument()),
Tag::S(b) => t_new(Tid::S, b.to_daletl_body(), NA),
Tag::Sup(b) => t_new(Tid::Sup, b.to_daletl_body(), NA),
Tag::Sub(b) => t_new(Tid::Sub, b.to_daletl_body(), NA),
Tag::Disc(b) => t_new(Tid::Disc, b.to_daletl_body(), NA),
Tag::Bl(b, a) => t_new(Tid::Bl, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Carousel(b) => t_new(Tid::Carousel, b.to_daletl_body(), NA),
Tag::Code(s, a) => t_new(Tid::Code, s.to_daletl_body(), a.to_daletl_argument()),
}
}
}
pub trait ToDaletlBody {
fn to_daletl_body(self) -> daletl::Body;
}
pub trait ToDaletlArgument {
fn to_daletl_argument(self) -> daletl::Argument;
}
#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive)]
#[repr(u8)]
pub enum HeadingLevel {
One = 1,
Two,
Three,
Four,
Five,
Six,
}
impl ToDaletlArgument for HeadingLevel {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
HeadingLevel::One => NA,
HeadingLevel::Two => 2u8.to_daletl_argument(),
HeadingLevel::Three => 3u8.to_daletl_argument(),
HeadingLevel::Four => 4u8.to_daletl_argument(),
HeadingLevel::Five => 5u8.to_daletl_argument(),
HeadingLevel::Six => 6u8.to_daletl_argument(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive)]
#[repr(u8)]
pub enum AlignArgument {
Start,
Center,
End,
}
impl ToDaletlArgument for AlignArgument {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
Self::Start => NA,
Self::Center => 1u8.to_daletl_argument(),
Self::End => 2u8.to_daletl_argument(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TextOrNumberArgument {
Text(String),
Number(u8),
}
impl ToDaletlArgument for TextOrNumberArgument {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
Self::Number(n) => n.to_daletl_argument(),
Self::Text(s) => s.to_daletl_argument(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TextOrNullArgument {
Text(String),
Null,
}
impl ToDaletlArgument for TextOrNullArgument {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
Self::Text(s) => s.to_daletl_argument(),
Self::Null => NA,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Body {
Text(String),
Tags(Vec<Tag>),
Null,
}
impl ToDaletlBody for Body {
fn to_daletl_body(self) -> daletl::Body {
match self {
Body::Null => NB,
Body::Tags(v) => v.to_daletl_body(),
Body::Text(v) => v.to_daletl_body(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Argument {
Text(String),
Number(u8),
Null,
}
impl ToDaletlArgument for Argument {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
Argument::Null => NA,
Argument::Number(v) => v.to_daletl_argument(),
Argument::Text(v) => v.to_daletl_argument(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NotNullArgument {
Text(String),
Number(u8),
}
impl ToDaletlArgument for NotNullArgument {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
NotNullArgument::Number(v) => v.to_daletl_argument(),
NotNullArgument::Text(v) => v.to_daletl_argument(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NotNullBody {
Text(String),
Tags(Vec<Tag>),
}
impl ToDaletlBody for NotNullBody {
fn to_daletl_body(self) -> daletl::Body {
match self {
NotNullBody::Text(v) => v.to_daletl_body(),
NotNullBody::Tags(v) => v.to_daletl_body(),
}
}
}
impl ToDaletlBody for Vec<Tag> {
fn to_daletl_body(self) -> daletl::Body {
daletl::Body::Tags(self.to_daletl())
}
}
impl ToDaletl for Vec<Tag> {
fn to_daletl(self) -> Vec<daletl::Tag> {
self.into_iter().map(|tag| tag.to_daletl_tag()).collect()
}
}
impl ToDaletlBody for String {
fn to_daletl_body(self) -> daletl::Body {
daletl::Body::Text(self)
}
}
impl ToDaletlArgument for String {
fn to_daletl_argument(self) -> daletl::Argument {
daletl::Argument::Text(self)
}
}
impl ToDaletlArgument for u8 {
fn to_daletl_argument(self) -> daletl::Argument {
daletl::Argument::Number(self)
}
}

13
src/commands.rs Normal file
View file

@ -0,0 +1,13 @@
use clap::{Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(name = "cimengine", bin_name = "cimengine")]
#[command(about = "CIMEngine build tools")]
pub struct Cli {
#[command(subcommand)]
pub cmd: Commands,
}
#[derive(Debug, Subcommand)]
#[clap(author, version, about)]
pub enum Commands {}

95
src/daletl.rs Normal file
View file

@ -0,0 +1,95 @@
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use num_enum::TryFromPrimitive;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Tag {
pub id: Tid,
pub body: Body,
pub argument: Argument,
}
impl Tag {
#[inline]
pub fn new(id: Tid, body: Body, argument: Argument) -> Tag {
Tag { id, body, argument }
}
}
pub fn t_new(id: Tid, body: Body, argument: Argument) -> Tag {
Tag::new(id, body, argument)
}
pub trait IsNull {
fn is_null(&self) -> bool;
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(untagged)]
pub enum Body {
Text(String),
Tags(Vec<Tag>),
Null,
}
impl IsNull for Body {
fn is_null(&self) -> bool {
match self {
Self::Null => true,
_ => false,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(untagged)]
pub enum Argument {
Text(String),
Number(u8),
Null,
}
impl IsNull for Argument {
fn is_null(&self) -> bool {
match self {
Self::Null => true,
_ => false,
}
}
}
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, PartialEq, Eq, TryFromPrimitive, Copy)]
#[repr(u8)]
/// Tag Id
pub enum Tid {
El,
H,
P,
Br,
Ul,
Ol,
Row,
Link,
Navlink,
Btn,
Navbtn,
Img,
Table,
Tcol,
Tpcol,
Hr,
B,
I,
Bq,
Footlnk,
Footn,
A,
S,
Sup,
Sub,
Disc,
Bl,
Carousel,
Code,
}

110
src/daletpack/encode.rs Normal file
View file

@ -0,0 +1,110 @@
use crate::daletl::{Argument, Body, IsNull, Tag, Tid};
use super::{DaletPackError, TypeId};
pub fn encode(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
Ok(zstd::bulk::compress(&encode_no_compress(root)?, 5)
.map_err(|_| DaletPackError::ZstdCompressError)?)
}
pub fn encode_no_compress(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
if root.len() > 2usize.pow(32) {
return Err(DaletPackError::RootMaxSizeExceeded);
}
let mut bv: Vec<u8> = Vec::new();
for tag in root {
write_tag(&mut bv, tag)?;
}
Ok(bv)
}
fn write_int(bv: &mut Vec<u8>, n: u8) {
bv.push(1);
bv.push(n);
}
fn write_str(bv: &mut Vec<u8>, string: &String) -> Result<(), DaletPackError> {
let size = string.len();
if size > 2usize.pow(32) {
return Err(DaletPackError::StrMaxSizeExceeded);
}
if size <= 256 {
bv.push(TypeId::Str8 as u8);
bv.push((size - 1) as u8);
} else if size <= 65536 {
bv.push(TypeId::Str16 as u8);
bv.extend(((size - 1) as u16).to_be_bytes());
} else {
bv.push(TypeId::Str32 as u8);
bv.extend(((size - 1) as u32).to_be_bytes());
}
bv.extend_from_slice(string.as_bytes());
Ok(())
}
fn write_array(bv: &mut Vec<u8>, arr: &Vec<Tag>) -> Result<(), DaletPackError> {
if arr.len() > 2usize.pow(32) {
return Err(DaletPackError::ArrMaxSizeExceeded);
}
bv.push(TypeId::TagArray as u8);
for tag in arr {
write_tag(bv, tag)?;
}
bv.push(TypeId::TagArrayEnd as u8);
Ok(())
}
fn write_tag(bv: &mut Vec<u8>, tag: &Tag) -> Result<(), DaletPackError> {
if tag.id == Tid::El {
write_tag_body(bv, &tag.body)?;
} else if tag.body.is_null() && tag.argument.is_null() {
bv.push(TypeId::TagId as u8);
bv.push(tag.id as u8);
} else if tag.argument.is_null() {
bv.push(TypeId::TagIdBody as u8);
bv.push(tag.id as u8);
write_tag_body(bv, &tag.body)?;
} else if tag.body.is_null() {
bv.push(TypeId::TagIdArgument as u8);
bv.push(tag.id as u8);
write_tag_argument(bv, &tag.argument)?;
} else {
bv.push(TypeId::TagIdBodyArgument as u8);
bv.push(tag.id as u8);
write_tag_body(bv, &tag.body)?;
write_tag_argument(bv, &tag.argument)?;
}
Ok(())
}
fn write_tag_body(bv: &mut Vec<u8>, body: &Body) -> Result<(), DaletPackError> {
match body {
Body::Text(s) => write_str(bv, s)?,
Body::Tags(tags) => write_array(bv, tags)?,
Body::Null => Err(DaletPackError::WriteNullBody)?,
};
Ok(())
}
fn write_tag_argument(bv: &mut Vec<u8>, argument: &Argument) -> Result<(), DaletPackError> {
match argument {
Argument::Text(s) => write_str(bv, s)?,
Argument::Number(n) => write_int(bv, *n),
Argument::Null => Err(DaletPackError::WriteNullArgument)?,
};
Ok(())
}

6
src/daletpack/mod.rs Normal file
View file

@ -0,0 +1,6 @@
mod encode;
mod types;
pub mod utils;
pub use encode::*;
pub use types::*;

27
src/daletpack/types.rs Normal file
View file

@ -0,0 +1,27 @@
use num_enum::TryFromPrimitive;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DaletPackError {
StrMaxSizeExceeded,
ArrMaxSizeExceeded,
RootMaxSizeExceeded,
ZstdCompressError,
WriteNullBody,
WriteNullArgument,
}
#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive, Copy)]
#[repr(u8)]
pub enum TypeId {
Int8 = 1,
Str8 = 4,
Str16,
Str32,
TagArray,
TagArrayEnd,
TagId = 12,
TagIdBody,
TagIdArgument,
TagIdBodyArgument,
}

3
src/daletpack/utils.rs Normal file
View file

@ -0,0 +1,3 @@
pub fn compress_zstd(data: &Vec<u8>) -> std::io::Result<Vec<u8>> {
zstd::bulk::compress(data, 22)
}

8
src/lib.rs Normal file
View file

@ -0,0 +1,8 @@
#[cfg(feature = "types")]
pub mod daletl;
#[cfg(feature = "types")]
pub mod abstractions;
#[cfg(feature = "daletpack")]
pub mod daletpack;

3
src/main.rs Normal file
View file

@ -0,0 +1,3 @@
mod commands;
fn main() {}

17
tests/bench.md Normal file
View file

@ -0,0 +1,17 @@
# Heading 1
## Heading 2
Some **bold** *italic* ~~strike~~
`Hello world`
- abc
- def
- defabc
- defdef
- xyz
Lorem ipsum [![](https://my-picture)](https://some-link) dolor sit amet consequetur adipiscing elit
| col1 | col2 | col3 |
| ----------- | -------- | ---- |
| Never gonna | give you | up |

115
tests/bench.rs Normal file
View file

@ -0,0 +1,115 @@
use dalet::{
abstractions::{Body, HeadingLevel, NotNullBody, Tag, TextOrNullArgument, ToDaletl},
daletpack::*,
};
use flate2::Compression;
use std::io::{read_to_string, Write};
#[macro_export]
macro_rules! iprint {
($name:expr, $func:expr) => {{
let start = std::time::Instant::now();
let result = $func;
let elapsed = start.elapsed();
println!("{} ({:#?}): {} bytes", $name, elapsed, result.len());
result
}};
}
pub fn compress_deflate(data: &Vec<u8>) -> std::io::Result<Vec<u8>> {
let mut c = flate2::write::DeflateEncoder::new(Vec::new(), Compression::default());
c.write(data)?;
c.finish()
}
pub fn compress_zlib(data: &Vec<u8>) -> std::io::Result<Vec<u8>> {
let mut c = flate2::write::ZlibEncoder::new(Vec::new(), Compression::default());
c.write(data)?;
c.finish()
}
#[test]
fn bench() {
let page: Vec<Tag> = vec![
Tag::H("I am heading".to_owned(), HeadingLevel::One),
Tag::H("Heading 2".to_owned(), HeadingLevel::Two),
Tag::El(NotNullBody::Tags(vec![
Tag::El(NotNullBody::Text("Some ".to_owned())),
Tag::B("bold".to_owned()),
Tag::I("italic".to_owned()),
Tag::S("strike".to_owned()),
])),
Tag::Br,
Tag::Code("Hello world".to_owned(), TextOrNullArgument::Null),
Tag::Br,
Tag::Ol(vec![
Tag::El(NotNullBody::Text("abc".to_owned())),
Tag::El(NotNullBody::Tags(vec![
Tag::El(NotNullBody::Text("def".to_owned())),
Tag::Ol(vec![
Tag::El(NotNullBody::Text("defabc".to_owned())),
Tag::El(NotNullBody::Text("defdef".to_owned())),
]),
])),
Tag::El(NotNullBody::Text("xyz".to_owned())),
]),
Tag::Br,
Tag::El(NotNullBody::Tags(vec![
Tag::El(NotNullBody::Text("Lorem ipsum ".to_owned())),
Tag::Link(
Body::Tags(vec![Tag::Img("https://my-picture".to_owned())]),
"https://some-link".to_owned(),
),
Tag::El(NotNullBody::Text(
" dolor sit amet consequetur adipiscing elit".to_owned(),
)),
])),
Tag::Table(vec![
Tag::Tpcol(vec![
Tag::El(NotNullBody::Text("Col 1".to_owned())),
Tag::El(NotNullBody::Text("Col 2".to_owned())),
Tag::El(NotNullBody::Text("Col 3".to_owned())),
]),
Tag::Tcol(vec![
Tag::El(NotNullBody::Text("Never gonna".to_owned())),
Tag::El(NotNullBody::Text("give you".to_owned())),
Tag::El(NotNullBody::Text("up".to_owned())),
]),
]),
];
let dalet_page = page.to_daletl();
let markdown = iprint!("Markdown", include_str!("./bench.md").as_bytes().to_vec());
let daletpack = iprint!("Daletpack", encode_no_compress(&dalet_page).unwrap());
let messagepack = iprint!("Messagepack", rmp_serde::to_vec(&dalet_page).unwrap());
let bincode = iprint!("Bincode", bincode::serialize(&dalet_page).unwrap());
println!();
iprint!("Markdown zstd", utils::compress_zstd(&markdown).unwrap());
iprint!("Daletpack zstd", utils::compress_zstd(&daletpack).unwrap());
iprint!(
"Messagepack zstd",
utils::compress_zstd(&messagepack).unwrap()
);
iprint!("Bincode zstd", utils::compress_zstd(&bincode).unwrap());
println!();
iprint!("Markdown Zlib", compress_zlib(&markdown).unwrap());
iprint!("Daletpack Zlib", compress_zlib(&daletpack).unwrap());
iprint!("Messagepack Zlib", compress_zlib(&messagepack).unwrap());
iprint!("Bincode Zlib", compress_zlib(&bincode).unwrap());
println!();
iprint!("Markdown deflate", compress_deflate(&markdown).unwrap());
iprint!("Daletpack deflate", compress_deflate(&daletpack).unwrap());
iprint!(
"Messagepack deflate",
compress_deflate(&messagepack).unwrap()
);
iprint!("Bincode deflate", compress_deflate(&bincode).unwrap());
}