From 9ac06199bd0e5623e2310de8eddffa8dad81a033 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Sun, 7 Dec 2025 02:25:49 +0300 Subject: [PATCH] Dsl and some simple handlers --- .cargo/config.toml | 2 + .gitignore | 3 ++ Cargo.toml | 14 +++++ src/default_handlers/enums.rs | 60 ++++++++++++++++++++++ src/default_handlers/floats.rs | 38 ++++++++++++++ src/default_handlers/integers.rs | 56 ++++++++++++++++++++ src/default_handlers/mod.rs | 7 +++ src/dsl.rs | 88 ++++++++++++++++++++++++++++++++ src/lib.rs | 2 + 9 files changed, 270 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/default_handlers/enums.rs create mode 100644 src/default_handlers/floats.rs create mode 100644 src/default_handlers/integers.rs create mode 100644 src/default_handlers/mod.rs create mode 100644 src/dsl.rs create mode 100644 src/lib.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..d4fa5d9 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[registries] +landgrafhomyak = { index = "sparse+https://cargo.landgrafhomyak.ru/" } \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b5488f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea/ +Cargo.lock +target/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..00addcc --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "json-decoder-api-0" +edition = "2024" + + +[lints] +rust = { nonstandard_style = "allow" } + +[workspace] +#members = ["macro", "macro/parser"] + +[patch.landgrafhomyak] +json-decoder-api-0-macro-0 = { path = "macro" } +json-decoder-api-0-macro-0-parser-0 = { path = "macro/parser" } diff --git a/src/default_handlers/enums.rs b/src/default_handlers/enums.rs new file mode 100644 index 0000000..21704a3 --- /dev/null +++ b/src/default_handlers/enums.rs @@ -0,0 +1,60 @@ +use crate::dsl::{BooleanHandler, FloatHandler, IntegerHandler, NoValueHandler, NullHandler}; +use std::marker::PhantomData; + +pub struct Handler_Boolean { + store: StoreFn, + __phantom: PhantomData, +} +impl Handler_Boolean { + pub fn create(f: StoreFn) -> Self { + return Self { + store: f, + __phantom: PhantomData::default(), + }; + } +} +impl BooleanHandler for Handler_Boolean { + fn handleBoolean(&self, dst: &mut S, value: bool) { + (self.store)(dst, value); + } +} + +pub struct Handler_Null { + store: StoreFn, + __phantom: PhantomData, +} + +impl Handler_Null { + pub fn create(f: StoreFn) -> Self { + return Self { + store: f, + __phantom: PhantomData::default(), + }; + } +} + +impl NullHandler for Handler_Null { + fn handleNull(&self, dst: &mut S) { + (self.store)(dst); + } +} + +pub struct Handler_NoValue { + store: StoreFn, + __phantom: PhantomData, +} + +impl Handler_NoValue { + pub fn create(f: StoreFn) -> Self { + return Self { + store: f, + __phantom: PhantomData::default(), + }; + } +} + +impl NoValueHandler for Handler_NoValue { + fn handleNoValue(&self, dst: &mut S) { + (self.store)(dst); + } +} diff --git a/src/default_handlers/floats.rs b/src/default_handlers/floats.rs new file mode 100644 index 0000000..01a8283 --- /dev/null +++ b/src/default_handlers/floats.rs @@ -0,0 +1,38 @@ +use crate::dsl::{FloatHandler, IntegerHandler}; +use std::marker::PhantomData; + +pub struct Handler_F64 { + store: StoreFn, + __phantom: PhantomData, +} +impl Handler_F64 { + pub fn create(f: StoreFn) -> Self { + return Self { + store: f, + __phantom: PhantomData::default(), + }; + } +} +impl FloatHandler for Handler_F64 { + fn handleFloat(&self, dst: &mut S, value: f64) { + (self.store)(dst, value); + } +} + +pub struct Handler_F32 { + store: StoreFn, + __phantom: PhantomData, +} +impl Handler_F32 { + pub fn create(f: StoreFn) -> Self { + return Self { + store: f, + __phantom: PhantomData::default(), + }; + } +} +impl FloatHandler for Handler_F32 { + fn handleFloat(&self, dst: &mut S, value: f64) { + (self.store)(dst, value as f32); + } +} diff --git a/src/default_handlers/integers.rs b/src/default_handlers/integers.rs new file mode 100644 index 0000000..1418a1d --- /dev/null +++ b/src/default_handlers/integers.rs @@ -0,0 +1,56 @@ +use crate::dsl::IntegerHandler; +use std::marker::PhantomData; + +macro_rules! defineIntegerHandler { + ($vis:vis $name:ident < $int_type:ty >) => { + $vis struct $name { + store: StoreFn, + __phantom: PhantomData + } + + impl $name { + pub fn create(f: StoreFn) -> Self { + return Self { + store: f, + __phantom: PhantomData::default() + } + } + } + + impl IntegerHandler for $name { + fn handleFixedInteger(&self, dst: &mut S, value: u64, isNegative: bool) { + let downcasted: $int_type; + + if isNegative { + if <$int_type>::MIN >= 0 || value > (<$int_type>::abs_diff(0, <$int_type>::MIN)) as u64 { + panic!( + "Integer underflow: expected in range {}..={}, got -{}", + <$int_type>::MIN, <$int_type>::MAX, value + ); + } + downcasted = i64::strict_sub_unsigned(0i64, value as u64) as $int_type; + } else { + if value > (<$int_type>::MAX as u64) { + panic!( + "Integer overflow: expected in range {}..={}, got {}", + <$int_type>::MIN, <$int_type>::MAX, value + ); + } + downcasted = value as $int_type; + } + + (self.store)(dst, downcasted); + return; + } + } + } +} + +defineIntegerHandler!( pub Handler_U8 ); +defineIntegerHandler!( pub Handler_S8 ); +defineIntegerHandler!( pub Handler_U16 ); +defineIntegerHandler!( pub Handler_S16 ); +defineIntegerHandler!( pub Handler_U32 ); +defineIntegerHandler!( pub Handler_S32 ); +defineIntegerHandler!( pub Handler_U64 ); +defineIntegerHandler!( pub Handler_S64 ); diff --git a/src/default_handlers/mod.rs b/src/default_handlers/mod.rs new file mode 100644 index 0000000..f693c57 --- /dev/null +++ b/src/default_handlers/mod.rs @@ -0,0 +1,7 @@ +mod integers; +mod floats; +mod enums; + +pub use integers::*; +pub use floats::*; +pub use enums::*; \ No newline at end of file diff --git a/src/dsl.rs b/src/dsl.rs new file mode 100644 index 0000000..3ba104f --- /dev/null +++ b/src/dsl.rs @@ -0,0 +1,88 @@ +pub trait IntegerHandler: Sized { + fn handleFixedInteger(&self, dst: &mut S, value: u64, isNegative: bool); +} + +pub trait FloatHandler: Sized { + fn handleFloat(&self, dst: &mut S, value: f64); +} + +pub trait BooleanHandler: Sized { + fn handleBoolean(&self, dst: &mut S, value: bool); +} + +pub trait NullHandler: Sized { + fn handleNull(&self, dst: &mut S); +} + +pub trait NoValueHandler: Sized { + fn handleNoValue(&self, dst: &mut S); +} + +pub trait ObjectHandler: Sized { + fn produceObject(&self) -> S; + fn storeObject(&self, dst: &mut P, value: S); +} + +pub trait StringHandler: Sized { + fn handleString(&self, dst: &mut P, value: T); +} + +pub trait ObjectConfigurationScope { + type K; + + fn ignoreKey_required(&mut self, name: &Self::K); + fn ignoreKey_optional(&mut self, name: &Self::K); + fn processKey(&mut self, name: &Self::K, config: impl ValueConfiguration); + fn processKey_optional( + &mut self, + name: &Self::K, + config: impl ValueConfiguration, + fallback: impl NoValueHandler, + ); +} +pub trait ObjectConfiguration

: Sized { + type S: Sized; + fn configureObject( + &self, + scope: &impl ArrayConfigurationScope, + ) -> impl ObjectHandler; +} + +pub trait ArrayHandler: Sized { + fn produceArray(&self) -> S; + fn storeArray(&self, dst: &mut P, value: S); +} + +pub trait ArrayConfigurationScope { + fn ignoreElements_required(&self, start: usize, endInclusive: Option); + fn ignoreElements_optional(&self, start: usize, endInclusive: Option); + fn processElements_required( + &self, + start: usize, + endInclusive: Option, + config: impl ValueConfiguration, + ); + fn processElements_optional( + &self, + start: usize, + endInclusive: Option, + config: impl ValueConfiguration, + ); +} + +pub trait ArrayConfiguration

: Sized { + type S: Sized; + fn configureArray( + &self, + scope: &impl ArrayConfigurationScope, + ) -> impl ObjectHandler; +} + +pub trait ValueConfiguration

: Sized { + fn integerHandler(&self) -> Option>; + fn floatHandler(&self) -> Option>; + fn booleanHandler(&self) -> Option>; + fn nullHandler(&self) -> Option>; + fn arrayHandler(&self) -> Option>; + fn objectHandler(&self) -> Option>; +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..a1e89db --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +pub mod dsl; +pub mod default_handlers;