From b24355e9ce794d3b8a5d6926a54b284adb0db748 Mon Sep 17 00:00:00 2001 From: James Munns Date: Thu, 10 Jul 2025 13:27:00 +0200 Subject: [PATCH 1/7] Introduce an explicit array type This avoids repetitive schema definitions of arrays --- .../src/impls/builtins_nostd.rs | 5 +++- source/postcard-schema-ng/src/key/hash.rs | 24 +++++++++++++++++ source/postcard-schema-ng/src/key/mod.rs | 26 ------------------- source/postcard-schema-ng/src/schema/fmt.rs | 11 ++++++++ source/postcard-schema-ng/src/schema/mod.rs | 12 +++++++++ source/postcard-schema-ng/src/schema/owned.rs | 16 ++++++++++++ source/postcard-schema-ng/tests/schema.rs | 5 +++- 7 files changed, 71 insertions(+), 28 deletions(-) diff --git a/source/postcard-schema-ng/src/impls/builtins_nostd.rs b/source/postcard-schema-ng/src/impls/builtins_nostd.rs index 7deb12da..b4e61db2 100644 --- a/source/postcard-schema-ng/src/impls/builtins_nostd.rs +++ b/source/postcard-schema-ng/src/impls/builtins_nostd.rs @@ -90,7 +90,10 @@ impl Schema for [T] { } impl Schema for [T; N] { - const SCHEMA: &'static DataModelType = &DataModelType::Tuple(&[T::SCHEMA; N]); + const SCHEMA: &'static DataModelType = &DataModelType::Array { + item: T::SCHEMA, + count: N, + }; } impl Schema for Range { diff --git a/source/postcard-schema-ng/src/key/hash.rs b/source/postcard-schema-ng/src/key/hash.rs index ee1c8cd3..8f2e4830 100644 --- a/source/postcard-schema-ng/src/key/hash.rs +++ b/source/postcard-schema-ng/src/key/hash.rs @@ -163,6 +163,18 @@ pub mod fnv1a64 { state } DataModelType::Schema => hash_update(state, &[0xE5]), + DataModelType::Array { item, count } => { + let mut state = hash_update(state, &[0x2B]); + let mut idx = 0; + + // TODO: Do we want to hash the len or something? I'm not + // sure how to handle this for different sizes of `usize`. + while idx < *count { + state = hash_sdm_type(state, item); + idx += 1; + } + state + } } } @@ -333,6 +345,18 @@ pub mod fnv1a64_owned { state } OwnedDataModelType::Schema => hash_update(state, &[0xE5]), + OwnedDataModelType::Array { item, count } => { + let mut state = hash_update(state, &[0x2B]); + let mut idx = 0; + + // TODO: Do we want to hash the len or something? I'm not + // sure how to handle this for different sizes of `usize`. + while idx < *count { + state = hash_sdm_type_owned(state, item); + idx += 1; + } + state + } } } diff --git a/source/postcard-schema-ng/src/key/mod.rs b/source/postcard-schema-ng/src/key/mod.rs index 45744cd1..066de51d 100644 --- a/source/postcard-schema-ng/src/key/mod.rs +++ b/source/postcard-schema-ng/src/key/mod.rs @@ -106,29 +106,3 @@ mod key_owned { } } } - -#[cfg(test)] -mod test { - use crate::{key::Key, schema::DataModelType, Schema}; - - #[test] - fn matches_old_postcard_rpc_defn() { - let old = &DataModelType::Struct { - name: "Key", - data: crate::schema::Data::Newtype(&DataModelType::Tuple(&[ - &DataModelType::U8, - &DataModelType::U8, - &DataModelType::U8, - &DataModelType::U8, - &DataModelType::U8, - &DataModelType::U8, - &DataModelType::U8, - &DataModelType::U8, - ])), - }; - - let new = ::SCHEMA; - - assert_eq!(old, new); - } -} diff --git a/source/postcard-schema-ng/src/schema/fmt.rs b/source/postcard-schema-ng/src/schema/fmt.rs index c247046d..34a12d76 100644 --- a/source/postcard-schema-ng/src/schema/fmt.rs +++ b/source/postcard-schema-ng/src/schema/fmt.rs @@ -39,6 +39,7 @@ pub fn is_prim(osdmty: &OwnedDataModelType) -> bool { OwnedDataModelType::Unit => true, OwnedDataModelType::Seq(_) => false, OwnedDataModelType::Tuple(_) => false, + OwnedDataModelType::Array { item, count: _ } => is_prim(item), OwnedDataModelType::Map { key, val } => is_prim(key) && is_prim(val), OwnedDataModelType::Struct { .. } => false, OwnedDataModelType::Enum { .. } => false, @@ -146,6 +147,13 @@ pub fn fmt_owned_dmt_to_buf(dmt: &OwnedDataModelType, buf: &mut String, top_leve *buf += "()"; } } + OwnedDataModelType::Array { item, count } => { + *buf += "["; + fmt_owned_dmt_to_buf(item, buf, false); + *buf += "; "; + *buf += &format!("{count}"); + *buf += "]"; + } OwnedDataModelType::Map { key, val } => { *buf += "Map<"; fmt_owned_dmt_to_buf(key, buf, false); @@ -244,6 +252,9 @@ pub fn discover_tys( discover_tys(v, set); } } + OwnedDataModelType::Array { item, count: _ } => { + discover_tys(item, set); + } OwnedDataModelType::Map { key, val } => { discover_tys(key, set); discover_tys(val, set); diff --git a/source/postcard-schema-ng/src/schema/mod.rs b/source/postcard-schema-ng/src/schema/mod.rs index 15d983df..863f66d6 100644 --- a/source/postcard-schema-ng/src/schema/mod.rs +++ b/source/postcard-schema-ng/src/schema/mod.rs @@ -101,6 +101,18 @@ pub enum DataModelType { /// The "Tuple" Serde Data Model Type Tuple(&'static [&'static Self]), + /// The Array type: Not part of the Serde Data Model + /// + /// This is for fixed length arrays like [T; N], in earlier + /// versions of the schema, we mapped this to a Tuple, which + /// worked but makes schemas unfortunately long. + Array { + /// The array element's type + item: &'static Self, + /// The number of items in the fixed size array + count: usize, + }, + /// The "Map" Serde Data Model Type Map { /// The map "Key" type diff --git a/source/postcard-schema-ng/src/schema/owned.rs b/source/postcard-schema-ng/src/schema/owned.rs index 978ff94c..a0e8a426 100644 --- a/source/postcard-schema-ng/src/schema/owned.rs +++ b/source/postcard-schema-ng/src/schema/owned.rs @@ -113,6 +113,18 @@ pub enum OwnedDataModelType { /// The "Tuple" Serde Data Model Type Tuple(Box<[Self]>), + /// The Array type: Not part of the Serde Data Model + /// + /// This is for fixed length arrays like [T; N], in earlier + /// versions of the schema, we mapped this to a Tuple, which + /// worked but makes schemas unfortunately long. + Array { + /// The array element's type + item: Box, + /// The number of items in the fixed size array + count: usize, + }, + /// The "Map" Serde Data Model Type Map { /// The map "Key" type @@ -166,6 +178,10 @@ impl From<&DataModelType> for OwnedDataModelType { DataModelType::Unit => Self::Unit, DataModelType::Seq(s) => Self::Seq(Box::new((*s).into())), DataModelType::Tuple(t) => Self::Tuple(t.iter().map(|i| (*i).into()).collect()), + DataModelType::Array { item, count } => Self::Array { + item: Box::new((*item).into()), + count: *count, + }, DataModelType::Map { key, val } => Self::Map { key: Box::new((*key).into()), val: Box::new((*val).into()), diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index 542177dc..0c801881 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -117,7 +117,10 @@ fn test_struct_serialize() { }, &NamedField { name: "e", - ty: &DataModelType::Tuple(&[u8::SCHEMA; 10]), + ty: &DataModelType::Array { + item: u8::SCHEMA, + count: 10 + }, }, &NamedField { name: "f", From 2956f475130161896e2a111723e959eea2f5095b Mon Sep 17 00:00:00 2001 From: James Munns Date: Thu, 10 Jul 2025 18:12:48 +0200 Subject: [PATCH 2/7] lol interning --- source/postcard-schema-ng/src/key/mod.rs | 2 +- .../postcard-schema-ng/src/schema/intern.rs | 641 ++++++++++++++++++ source/postcard-schema-ng/src/schema/mod.rs | 2 + source/postcard-schema-ng/tests/schema.rs | 16 +- 4 files changed, 656 insertions(+), 5 deletions(-) create mode 100644 source/postcard-schema-ng/src/schema/intern.rs diff --git a/source/postcard-schema-ng/src/key/mod.rs b/source/postcard-schema-ng/src/key/mod.rs index 066de51d..850cf759 100644 --- a/source/postcard-schema-ng/src/key/mod.rs +++ b/source/postcard-schema-ng/src/key/mod.rs @@ -50,7 +50,7 @@ impl core::fmt::Debug for Key { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("Key(")?; for b in self.0.iter() { - f.write_fmt(format_args!("{} ", b))?; + f.write_fmt(format_args!("{b} "))?; } f.write_str(")") } diff --git a/source/postcard-schema-ng/src/schema/intern.rs b/source/postcard-schema-ng/src/schema/intern.rs new file mode 100644 index 00000000..206beeec --- /dev/null +++ b/source/postcard-schema-ng/src/schema/intern.rs @@ -0,0 +1,641 @@ +#![allow(missing_docs, dead_code)] + +use serde::Serialize; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternStrRef { + offset: usize, + len: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternDataModelTypeRef { + idx: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternDataModelGroupRef { + offset: usize, + len: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternNamedFieldGroupRef { + offset: usize, + len: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternVariantGroupRef { + offset: usize, + len: usize, +} + +/// This enum lists which of the Data Model Types apply to a given type. This describes how the +/// type is encoded on the wire. +/// +/// This enum contains all Serde Data Model types as well as a "Schema" Type, +/// which corresponds to [`DataModelType`] itself. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub enum InternDataModelType { + /// The `bool` Serde Data Model Type + Bool, + + /// The `i8` Serde Data Model Type + I8, + + /// The `u8` Serde Data Model Type + U8, + + /// A variably encoded i16 + I16, + + /// A variably encoded i32 + I32, + + /// A variably encoded i64 + I64, + + /// A variably encoded i128 + I128, + + /// A variably encoded u16 + U16, + + /// A variably encoded u32 + U32, + + /// A variably encoded u64 + U64, + + /// A variably encoded u128 + U128, + + /// A variably encoded usize + Usize, + + /// A variably encoded isize + Isize, + + /// The `f32` Serde Data Model Type + F32, + + /// The `f64` Serde Data Model Type + F64, + + /// The `char` Serde Data Model Type + Char, + + /// The `String` Serde Data Model Type + String, + + /// The `&[u8]` Serde Data Model Type + ByteArray, + + /// The `Option` Serde Data Model Type + Option(InternDataModelTypeRef), + + /// The `()` Serde Data Model Type + Unit, + + /// The "Sequence" Serde Data Model Type + Seq(InternDataModelTypeRef), + + /// The "Tuple" Serde Data Model Type + Tuple(InternDataModelGroupRef), + + /// The Array type: Not part of the Serde Data Model + /// + /// This is for fixed length arrays like [T; N], in earlier + /// versions of the schema, we mapped this to a Tuple, which + /// worked but makes schemas unfortunately long. + Array { + /// The array element's type + item: InternDataModelTypeRef, + /// The number of items in the fixed size array + count: usize, + }, + + /// The "Map" Serde Data Model Type + Map { + /// The map "Key" type + key: InternDataModelTypeRef, + /// The map "Value" type + val: InternDataModelTypeRef, + }, + + /// One of the struct Serde Data Model types + Struct { + /// The name of this struct + name: InternStrRef, + /// The data contained in this struct + data: Data, + }, + + /// The "Enum" Serde Data Model Type (which contains any of the "Variant" types) + Enum { + /// The name of this struct + name: InternStrRef, + /// The variants contained in this enum + variants: InternVariantGroupRef, + }, + + /// A [`DataModelType`]/[`OwnedDataModelType`](owned::OwnedDataModelType) + Schema, +} + +/// The contents of a struct or enum variant. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub enum Data { + /// The "Unit Struct" or "Unit Variant" Serde Data Model Type + Unit, + + /// The "Newtype Struct" or "Newtype Variant" Serde Data Model Type + Newtype(InternDataModelTypeRef), + + /// The "Tuple Struct" or "Tuple Variant" Serde Data Model Type + Tuple(InternDataModelGroupRef), + + /// The "Struct" or "Struct Variant" Serde Data Model Type + Struct(InternNamedFieldGroupRef), +} + +// TODO: +// +// * First populate the tuples, they need to have types in groups +// * We might want to keep the "tuple list" and "other items" in separate lists +// * we can merge + +/// This represents a named struct field. +/// +/// For example, in `struct Ex { a: u32 }` the field `a` would be reflected as +/// `NamedField { name: "a", ty: DataModelType::U32 }`. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternNamedField { + /// The name of this field + pub name: InternStrRef, + /// The type of this field + pub ty: InternDataModelTypeRef, +} + +/// An enum variant e.g. `T::Bar(...)` +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub struct InternVariant { + /// The name of this variant + pub name: InternStrRef, + /// The data contained in this variant + pub data: Data, +} + +pub struct IntermedSchema< + 'a, + const DMTS: usize, + const RUNDMTS: usize, + const NFS: usize, + const VNTS: usize, +> { + strs: &'a str, + run_dmts: [InternDataModelType; RUNDMTS], + dmts: [InternDataModelType; DMTS], + nfs: [InternNamedField; NFS], + vnts: [InternVariant; VNTS], +} + +pub struct InternedSchema<'a, const DMTS: usize, const NFS: usize, const VNTS: usize> { + strs: &'a str, + dmts: [InternDataModelType; DMTS], + nfs: [InternNamedField; NFS], + vnts: [InternVariant; VNTS], +} + +pub mod ty_intern { + +} + +pub mod str_intern { + use crate::schema::{Data, DataModelType}; + + pub const fn collect_all_strings_data( + data: &Data, + ) -> ([&'static str; N], usize) { + let mut out = const { [""; N] }; + match data { + Data::Unit => (out, 0), + Data::Newtype(data_model_type) => collect_all_strings(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + let (sub, subct) = collect_all_strings::(data_model_types[idx]); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + idx += 1; + } + (out, count) + } + Data::Struct(named_fields) => { + let mut count = 0; + let mut idx = 0; + while idx < named_fields.len() { + out[count] = named_fields[idx].name; + count += 1; + + let (sub, subct) = collect_all_strings::(named_fields[idx].ty); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + idx += 1; + } + (out, count) + } + } + } + + pub const fn collect_all_strings( + data: &DataModelType, + ) -> ([&'static str; N], usize) { + let mut out = const { [""; N] }; + match data { + DataModelType::Bool => (out, 0), + DataModelType::I8 => (out, 0), + DataModelType::U8 => (out, 0), + DataModelType::I16 => (out, 0), + DataModelType::I32 => (out, 0), + DataModelType::I64 => (out, 0), + DataModelType::I128 => (out, 0), + DataModelType::U16 => (out, 0), + DataModelType::U32 => (out, 0), + DataModelType::U64 => (out, 0), + DataModelType::U128 => (out, 0), + DataModelType::Usize => (out, 0), + DataModelType::Isize => (out, 0), + DataModelType::F32 => (out, 0), + DataModelType::F64 => (out, 0), + DataModelType::Char => (out, 0), + DataModelType::String => (out, 0), + DataModelType::ByteArray => (out, 0), + DataModelType::Option(data_model_type) => collect_all_strings(data_model_type), + DataModelType::Unit => (out, 0), + DataModelType::Seq(data_model_type) => collect_all_strings(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + let (sub, subct) = collect_all_strings::(data_model_types[idx]); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + idx += 1; + } + (out, count) + } + DataModelType::Array { item, count: _ } => collect_all_strings(item), + DataModelType::Map { key, val } => { + // collect_all_strings(key) + collect_all_strings(val) + let mut count = 0; + + let (sub, subct) = collect_all_strings::(key); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + + let (sub, subct) = collect_all_strings::(val); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + + (out, count) + } + DataModelType::Struct { name, data } => { + let mut count = 0; + + out[count] = name; + count += 1; + + let (sub, subct) = collect_all_strings_data::(data); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + (out, count) + } + DataModelType::Enum { name, variants } => { + let mut count = 0; + let mut idx = 0; + + out[count] = name; + count += 1; + + while idx < variants.len() { + out[count] = variants[idx].name; + count += 1; + + let (sub, subct) = collect_all_strings_data::(&variants[idx].data); + let mut icount = 0; + while icount < subct { + out[count] = sub[icount]; + count += 1; + icount += 1; + } + idx += 1; + } + (out, count) + } + DataModelType::Schema => todo!(), + } + } + + pub const fn count_strings_data(data: &Data) -> usize { + match data { + Data::Unit => 0, + Data::Newtype(data_model_type) => count_strings(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_strings(data_model_types[idx]); + idx += 1; + } + count + } + Data::Struct(named_fields) => { + let mut count = 0; + let mut idx = 0; + while idx < named_fields.len() { + count += 1; // name + count += count_strings(named_fields[idx].ty); + idx += 1; + } + count + } + } + } + + pub const fn count_strings(data: &DataModelType) -> usize { + match data { + DataModelType::Bool => 0, + DataModelType::I8 => 0, + DataModelType::U8 => 0, + DataModelType::I16 => 0, + DataModelType::I32 => 0, + DataModelType::I64 => 0, + DataModelType::I128 => 0, + DataModelType::U16 => 0, + DataModelType::U32 => 0, + DataModelType::U64 => 0, + DataModelType::U128 => 0, + DataModelType::Usize => 0, + DataModelType::Isize => 0, + DataModelType::F32 => 0, + DataModelType::F64 => 0, + DataModelType::Char => 0, + DataModelType::String => 0, + DataModelType::ByteArray => 0, + DataModelType::Option(data_model_type) => count_strings(data_model_type), + DataModelType::Unit => 0, + DataModelType::Seq(data_model_type) => count_strings(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_strings(data_model_types[idx]); + idx += 1; + } + count + } + DataModelType::Array { item, count: _ } => count_strings(item), + DataModelType::Map { key, val } => count_strings(key) + count_strings(val), + DataModelType::Struct { name: _, data } => { + // 1 for name + 1 + count_strings_data(data) + } + DataModelType::Enum { name: _, variants } => { + // 1 for enum name + let mut count = 1; + let mut idx = 0; + while idx < variants.len() { + // 1 for variant name + count += 1; + count += count_strings_data(&variants[idx].data); + idx += 1; + } + count + } + DataModelType::Schema => todo!(), + } + } + + pub const fn sort_arr(mut arr: [&str; N]) -> [&str; N] { + if N < 2 { + return arr; + } + loop { + let mut swapped = false; + let mut i = 1; + while i < arr.len() { + // First, sort by len, longest first + let swap = if arr[i - 1].len() < arr[i].len() { + true + } else if arr[i - 1].len() == arr[i].len() { + // Then, if equal length, sort alphabetically + let mut swap = false; + let mut j = 0; + 'inner: while j < arr[i].len() { + if arr[i - 1].as_bytes()[j] > arr[i].as_bytes()[j] { + swap = true; + break 'inner; + } else if arr[i - 1].as_bytes()[j] < arr[i].as_bytes()[j] { + break 'inner; + } + j += 1; + } + swap + } else { + false + }; + + if swap { + let left = arr[i - 1]; + let right = arr[i]; + arr[i - 1] = right; + arr[i] = left; + swapped = true; + } + + i += 1; + } + + if !swapped { + break; + } + } + arr + } + + pub const fn streq(a: &str, b: &str) -> bool { + if a.len() != b.len() { + return false; + } + let a = a.as_bytes(); + let b = b.as_bytes(); + + let mut i = 0; + while i < a.len() { + if a[i] != b[i] { + return false; + } + i += 1; + } + true + } + + pub const fn str_contains(base: &str, frag: &str) -> bool { + if frag.len() > base.len() { + return false; + } + if streq(base, frag) { + return true; + } + if frag.is_empty() { + return true; + } + let base = base.as_bytes(); + let frag = frag.as_bytes(); + + let mut bi = 0; + 'outer: while bi < (base.len() - frag.len()) { + if base[bi] == frag[0] { + let mut off = 1; + while (off < frag.len()) && ((off + bi) < base.len()) { + if frag[off] != base[off + bi] { + bi += 1; + continue 'outer; + } + off += 1; + } + return true; + } + bi += 1; + } + false + } + + pub const fn dedupe_strings(strs: [&str; N]) -> ([&str; N], usize) { + let strs = sort_arr(strs); + let mut out = [""; N]; + let mut count = 0; + let mut idx = 0; + 'outer: while idx < strs.len() { + let mut icount = 0; + while icount < count { + if streq(out[icount], strs[idx]) { + // exact match + idx += 1; + continue 'outer; + } else if str_contains(out[icount], strs[idx]) { + // fragment match + idx += 1; + continue 'outer; + } + icount += 1; + } + // if we reach the end, no match was found. + out[count] = strs[idx]; + count += 1; + idx += 1; + } + + (out, count) + } + + pub const fn pack_down_str(strs: &[&'static str]) -> [&'static str; N] { + let mut out = [""; N]; + let mut idx = 0; + while idx < N { + out[idx] = strs[idx]; + idx += 1; + } + out + } + + pub const fn ttl_str_len(strs: &[&str]) -> usize { + let mut total = 0; + let mut idx = 0; + while idx < strs.len() { + total += strs[idx].len(); + idx += 1; + } + total + } + + pub const fn merge_strs(strs: &[&str]) -> [u8; N] { + let mut out = [0u8; N]; + let mut count = 0; + let mut idx = 0; + while idx < strs.len() { + let s = strs[idx].as_bytes(); + let mut icount = 0; + while icount < s.len() { + out[count] = s[icount]; + icount += 1; + count += 1; + } + idx += 1; + } + assert!(count == N); + out + } + + #[macro_export] + macro_rules! sintern { + ($schema_ty:ty) => { + const { + // How many un-de-duplicated strings exist in the schema? + const CT: usize = $crate::schema::intern::str_intern::count_strings( + <$schema_ty as postcard_schema_ng::Schema>::SCHEMA, + ); + // A tuple of strings, and the number actually used (should be the same?) + const STRS: ([&str; CT], usize) = + $crate::schema::intern::str_intern::collect_all_strings::( + <$schema_ty as postcard_schema_ng::Schema>::SCHEMA, + ); + // A tuple of de-duplicated and sorted strings + const DSTRS: ([&str; CT], usize) = + $crate::schema::intern::str_intern::dedupe_strings(STRS.0); + // The post-de-duplication len + const LEN: usize = DSTRS.1; + // An array of strs + const PSTRS: &[&str] = + &$crate::schema::intern::str_intern::pack_down_str::(&DSTRS.0); + // The total len (in bytes) of the strs + const LLEN: usize = $crate::schema::intern::str_intern::ttl_str_len(PSTRS); + // The strs, merged into a single array + const MERGED: &[u8] = + &$crate::schema::intern::str_intern::merge_strs::(PSTRS); + // And finally, turn it back into a str + match core::str::from_utf8(MERGED) { + Ok(s) => s, + Err(_e) => panic!(), + } + } + }; + } +} diff --git a/source/postcard-schema-ng/src/schema/mod.rs b/source/postcard-schema-ng/src/schema/mod.rs index 863f66d6..96074333 100644 --- a/source/postcard-schema-ng/src/schema/mod.rs +++ b/source/postcard-schema-ng/src/schema/mod.rs @@ -26,6 +26,8 @@ pub mod owned; #[cfg(any(feature = "use-std", feature = "alloc"))] pub mod fmt; +pub mod intern; + use serde::Serialize; /// This enum lists which of the Data Model Types apply to a given type. This describes how the diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index 0c801881..4fe851df 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -1,8 +1,7 @@ use postcard_schema_ng::{ - schema::{owned::OwnedDataModelType, Data, DataModelType, NamedField, Variant}, - Schema, + schema::{owned::OwnedDataModelType, Data, DataModelType, NamedField, Variant}, sintern, Schema }; -use std::path::PathBuf; +use std::{cmp::Ordering, path::PathBuf}; #[allow(unused)] #[derive(Schema)] @@ -181,6 +180,7 @@ struct TestStruct1 { #[allow(unused)] #[derive(Debug, Schema)] struct TestStruct2<'a> { + w: (u8, u16, u32), x: TestEnum<'a>, y: TestStruct1, z: Result, @@ -198,7 +198,7 @@ fn owned_punning() { // TODO: This is wildly repetitive, and likely could benefit from interning of // repeated types, strings, etc. - assert_eq!(ser_borrowed_schema.len(), 187); + assert_eq!(ser_borrowed_schema.len(), 194); // Check that we round-trip correctly let deser_borrowed_schema = @@ -224,6 +224,14 @@ enum TestEnum2 { Tup(u64, bool), } +#[test] +fn hacking() { + // emit_strings(TestStruct2::SCHEMA); + const SINTERN: &str = sintern!(TestStruct2); + println!("{SINTERN}"); + panic!("yay"); +} + #[test] fn newtype_vs_tuple() { assert_eq!( From 9e3d970bedc1b67c5c3cc7094fd8b8cf22ed8082 Mon Sep 17 00:00:00 2001 From: James Munns Date: Thu, 10 Jul 2025 23:45:06 +0200 Subject: [PATCH 3/7] Interning progress --- .../postcard-schema-ng/src/schema/intern.rs | 933 +++++++++++++++++- source/postcard-schema-ng/tests/schema.rs | 10 +- 2 files changed, 938 insertions(+), 5 deletions(-) diff --git a/source/postcard-schema-ng/src/schema/intern.rs b/source/postcard-schema-ng/src/schema/intern.rs index 206beeec..0f504d87 100644 --- a/source/postcard-schema-ng/src/schema/intern.rs +++ b/source/postcard-schema-ng/src/schema/intern.rs @@ -1,6 +1,10 @@ #![allow(missing_docs, dead_code)] use serde::Serialize; +use str_intern::streq; +use ty_intern::str_subslice; + +use super::{Data, DataModelType}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] pub struct InternStrRef { @@ -129,7 +133,7 @@ pub enum InternDataModelType { /// The name of this struct name: InternStrRef, /// The data contained in this struct - data: Data, + data: InternData, }, /// The "Enum" Serde Data Model Type (which contains any of the "Variant" types) @@ -146,7 +150,7 @@ pub enum InternDataModelType { /// The contents of a struct or enum variant. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub enum Data { +pub enum InternData { /// The "Unit Struct" or "Unit Variant" Serde Data Model Type Unit, @@ -184,10 +188,10 @@ pub struct InternVariant { /// The name of this variant pub name: InternStrRef, /// The data contained in this variant - pub data: Data, + pub data: InternData, } -pub struct IntermedSchema< +pub struct IntermediateSchema< 'a, const DMTS: usize, const RUNDMTS: usize, @@ -195,10 +199,338 @@ pub struct IntermedSchema< const VNTS: usize, > { strs: &'a str, + run_dmts: [InternDataModelType; RUNDMTS], + run_dmts_len: usize, + dmts: [InternDataModelType; DMTS], + dmts_len: usize, + nfs: [InternNamedField; NFS], + nfs_len: usize, + vnts: [InternVariant; VNTS], + vnts_len: usize, +} + +impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: usize> + IntermediateSchema<'a, DMTS, RUNDMTS, NFS, VNTS> +{ + const fn new(s: &'a str) -> Self { + const NULLSTR: InternStrRef = InternStrRef { offset: 0, len: 0 }; + Self { + strs: s, + run_dmts: [InternDataModelType::Schema; RUNDMTS], + run_dmts_len: 0, + dmts: [InternDataModelType::Schema; DMTS], + dmts_len: 0, + nfs: [InternNamedField { + name: NULLSTR, + ty: InternDataModelTypeRef { idx: 0 }, + }; NFS], + nfs_len: 0, + vnts: [InternVariant { + name: NULLSTR, + data: InternData::Unit, + }; VNTS], + vnts_len: 0, + } + } + + const fn run_dmts(&self) -> &[InternDataModelType] { + let (now, _later) = self.run_dmts.split_at(self.run_dmts_len); + now + } + + const fn dmts(&self) -> &[InternDataModelType] { + let (now, _later) = self.dmts.split_at(self.dmts_len); + now + } + + const fn nfs(&self) -> &[InternNamedField] { + let (now, _later) = self.nfs.split_at(self.nfs_len); + now + } + + const fn vnts(&self) -> &[InternVariant] { + let (now, _later) = self.vnts.split_at(self.vnts_len); + now + } + + /////// + + pub const fn is_data_match(&self, data: &Data, intern: &InternData) -> bool { + match (data, intern) { + (Data::Unit, InternData::Unit) => true, + (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { + self.is_dmt_match( + data_model_type, + &self.dmts()[intern_data_model_type_ref.idx], + ) + } + (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { + if data_model_types.len() != intern_data_model_group_ref.len { + return false; + } + let mut count = 0; + while count < data_model_types.len() { + let m = self.is_dmt_match( + data_model_types[count], + &self.dmts()[count + intern_data_model_group_ref.offset], + ); + if !m { + return false; + } + count += 1; + } + true + } + (Data::Struct(named_fields), InternData::Struct(intern_named_field_group_ref)) => { + if named_fields.len() != intern_named_field_group_ref.len { + return false; + } + let mut count = 0; + while count < named_fields.len() { + let offct = intern_named_field_group_ref.offset + count; + let inf = &self.nfs()[offct]; + if !streq( + named_fields[count].name, + str_subslice(self.strs, inf.name.offset, inf.name.len), + ) { + return false; + } + if !self.is_dmt_match(named_fields[count].ty, &self.dmts()[inf.ty.idx]) { + return false; + } + count += 1; + } + true + } + _ => false, + } + } + + pub const fn is_dmt_match(&self, dmt: &DataModelType, idmt: &InternDataModelType) -> bool { + match (idmt, dmt) { + (InternDataModelType::Bool, DataModelType::Bool) => true, + (InternDataModelType::I8, DataModelType::I8) => true, + (InternDataModelType::U8, DataModelType::U8) => true, + (InternDataModelType::I16, DataModelType::I16) => true, + (InternDataModelType::I32, DataModelType::I32) => true, + (InternDataModelType::I64, DataModelType::I64) => true, + (InternDataModelType::I128, DataModelType::I128) => true, + (InternDataModelType::U16, DataModelType::U16) => true, + (InternDataModelType::U32, DataModelType::U32) => true, + (InternDataModelType::U64, DataModelType::U64) => true, + (InternDataModelType::U128, DataModelType::U128) => true, + (InternDataModelType::Usize, DataModelType::Usize) => true, + (InternDataModelType::Isize, DataModelType::Isize) => true, + (InternDataModelType::F32, DataModelType::F32) => true, + (InternDataModelType::F64, DataModelType::F64) => true, + (InternDataModelType::Char, DataModelType::Char) => true, + (InternDataModelType::String, DataModelType::String) => true, + (InternDataModelType::ByteArray, DataModelType::ByteArray) => true, + ( + InternDataModelType::Option(intern_data_model_type_ref), + DataModelType::Option(data_model_type), + ) => self.is_dmt_match( + data_model_type, + &self.dmts()[intern_data_model_type_ref.idx], + ), + (InternDataModelType::Unit, DataModelType::Unit) => true, + ( + InternDataModelType::Seq(intern_data_model_type_ref), + DataModelType::Seq(data_model_type), + ) => self.is_dmt_match( + data_model_type, + &self.dmts()[intern_data_model_type_ref.idx], + ), + ( + InternDataModelType::Tuple(intern_data_model_group_ref), + DataModelType::Tuple(data_model_types), + ) => { + if intern_data_model_group_ref.len != data_model_types.len() { + return false; + } + let mut count = 0; + while count < data_model_types.len() { + let idm = intern_data_model_group_ref.offset + count; + if !self.is_dmt_match(data_model_types[count], &self.dmts()[idm]) { + return false; + } + count += 1; + } + true + } + ( + InternDataModelType::Array { item, count }, + DataModelType::Array { + item: ditem, + count: dcount, + }, + ) => (*count == *dcount) && self.is_dmt_match(ditem, &self.dmts()[item.idx]), + ( + InternDataModelType::Map { key, val }, + DataModelType::Map { + key: dkey, + val: dval, + }, + ) => { + self.is_dmt_match(dkey, &self.dmts()[key.idx]) + && self.is_dmt_match(dval, &self.dmts()[val.idx]) + } + ( + InternDataModelType::Struct { name, data }, + DataModelType::Struct { + name: dname, + data: ddata, + }, + ) => { + let name_match = streq(str_subslice(self.strs, name.offset, name.len), dname); + let data_match = self.is_data_match(ddata, data); + name_match && data_match + } + ( + InternDataModelType::Enum { name, variants }, + DataModelType::Enum { + name: dname, + variants: dvariants, + }, + ) => { + if !streq(str_subslice(self.strs, name.offset, name.len), dname) { + return false; + } + if variants.len != dvariants.len() { + return false; + } + let mut count = 0; + while count < dvariants.len() { + let ivar = &self.vnts()[variants.offset + count]; + if !streq( + dvariants[count].name, + str_subslice(self.strs, ivar.name.offset, ivar.name.len), + ) { + return false; + } + if !self.is_data_match(&dvariants[count].data, &ivar.data) { + return false; + } + count += 1; + } + true + } + (InternDataModelType::Schema, DataModelType::Schema) => todo!(), + _ => false, + } + } + + pub const fn find_run_dmt(&self, dmts: &[&DataModelType]) -> Option { + if self.dmts.len() < dmts.len() { + return None; + } + assert!(!dmts.is_empty()); + + let mut count = 0; + 'outer: while count < (self.dmts.len() - dmts.len()) { + let mut icount = 0; + while icount < dmts.len() { + if !self.is_dmt_match(dmts[icount], &self.dmts[count + icount]) { + count += 1; + continue 'outer; + } + icount += 1; + } + return Some(InternDataModelGroupRef { + offset: count, + len: dmts.len(), + }); + } + None + } + + ////// + + const fn slurp_run_dmts_data(&mut self, data: &Data) { + match data { + Data::Unit => (), + Data::Newtype(data_model_type) => self.slurp_run_dmts(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = 0; + while count < data_model_types.len() { + self.slurp_run_dmts(data_model_types[count]); + count += 1; + } + todo!() + }, + Data::Struct(named_fields) => { + let mut count = 0; + while count < named_fields.len() { + self.slurp_run_dmts(named_fields[count].ty); + count += 1; + } + }, + } + } + + const fn slurp_run_dmts(&mut self, dmt: &DataModelType) { + match dmt { + DataModelType::Bool => {}, + DataModelType::I8 => {}, + DataModelType::U8 => {}, + DataModelType::I16 => {}, + DataModelType::I32 => {}, + DataModelType::I64 => {}, + DataModelType::I128 => {}, + DataModelType::U16 => {}, + DataModelType::U32 => {}, + DataModelType::U64 => {}, + DataModelType::U128 => {}, + DataModelType::Usize => {}, + DataModelType::Isize => {}, + DataModelType::F32 => {}, + DataModelType::F64 => {}, + DataModelType::Char => {}, + DataModelType::String => {}, + DataModelType::ByteArray => {}, + DataModelType::Option(data_model_type) => self.slurp_run_dmts(data_model_type), + DataModelType::Unit => {}, + DataModelType::Seq(data_model_type) => self.slurp_run_dmts(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = 0; + while count < data_model_types.len() { + self.slurp_run_dmts(data_model_types[count]); + count += 1; + } + if self.find_run_dmt(data_model_types).is_none() { + // one pass over the types to push any subdeps to dmts, then + // a second pass to fill in the run dmts? + todo!() + } + }, + DataModelType::Array { item, count: _ } => self.slurp_run_dmts(item), + DataModelType::Map { key, val } => { + self.slurp_run_dmts(key); + self.slurp_run_dmts(val); + }, + DataModelType::Struct { name: _, data } => self.slurp_run_dmts_data(data), + DataModelType::Enum { name: _, variants } => { + let mut count = 0; + while count < variants.len() { + self.slurp_run_dmts_data(&variants[count].data); + count += 1; + } + }, + DataModelType::Schema => todo!(), + } + } + + const fn push_run_dmt(self, dmts: &[&DataModelType]) -> Self { + if self.find_run_dmt(dmts).is_some() { + return self; + } + todo!() + // didn't find, extend + } } pub struct InternedSchema<'a, const DMTS: usize, const NFS: usize, const VNTS: usize> { @@ -209,7 +541,600 @@ pub struct InternedSchema<'a, const DMTS: usize, const NFS: usize, const VNTS: u } pub mod ty_intern { + use crate::schema::intern::str_intern::streq; + use crate::schema::Data; + use crate::schema::DataModelType; + + use super::InternData; + use super::InternDataModelGroupRef; + use super::InternDataModelType; + use super::InternNamedField; + use super::InternVariant; + ////////////////////////////////////////////////////////////////////// + // RUN DMTS + ////////////////////////////////////////////////////////////////////// + + pub const fn count_run_dmts_data(data: &Data) -> usize { + match data { + Data::Unit => 0, + Data::Newtype(data_model_type) => count_run_dmts(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = data_model_types.len(); + let mut idx = 0; + while idx < data_model_types.len() { + count += count_run_dmts(data_model_types[idx]); + idx += 1; + } + count + } + Data::Struct(named_fields) => { + let mut count = 0; + let mut idx = 0; + while idx < named_fields.len() { + count += count_run_dmts(named_fields[idx].ty); + idx += 1; + } + count + } + } + } + + pub const fn count_run_dmts(dmt: &DataModelType) -> usize { + match dmt { + DataModelType::Bool => 0, + DataModelType::I8 => 0, + DataModelType::U8 => 0, + DataModelType::I16 => 0, + DataModelType::I32 => 0, + DataModelType::I64 => 0, + DataModelType::I128 => 0, + DataModelType::U16 => 0, + DataModelType::U32 => 0, + DataModelType::U64 => 0, + DataModelType::U128 => 0, + DataModelType::Usize => 0, + DataModelType::Isize => 0, + DataModelType::F32 => 0, + DataModelType::F64 => 0, + DataModelType::Char => 0, + DataModelType::String => 0, + DataModelType::ByteArray => 0, + DataModelType::Option(data_model_type) => count_run_dmts(data_model_type), + DataModelType::Unit => 0, + DataModelType::Seq(data_model_type) => count_run_dmts(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = data_model_types.len(); + let mut idx = 0; + while idx < data_model_types.len() { + count += count_run_dmts(data_model_types[idx]); + idx += 1; + } + count + } + DataModelType::Array { item, count: _ } => count_run_dmts(item), + DataModelType::Map { key, val } => count_run_dmts(key) + count_run_dmts(val), + DataModelType::Struct { name: _, data } => count_run_dmts_data(data), + DataModelType::Enum { name: _, variants } => { + let mut count = 0; + let mut idx = 0; + while idx < variants.len() { + count += count_run_dmts_data(&variants[idx].data); + idx += 1; + } + count + } + DataModelType::Schema => todo!(), + } + } + + ////////////////////////////////////////////////////////////////////// + // INTERN INTERN INTERN + ////////////////////////////////////////////////////////////////////// + + pub const fn str_subslice(s: &str, offset: usize, len: usize) -> &str { + let s = s.as_bytes(); + let (_before, now) = s.split_at(offset); + let (now, _after) = now.split_at(len); + match core::str::from_utf8(now) { + Ok(s) => s, + Err(_) => panic!(), + } + } + + pub const fn is_data_match( + data: &Data, + intern: &InternData, + idmts: &[InternDataModelType], + infs: &[InternNamedField], + ivars: &[InternVariant], + istrs: &str, + ) -> bool { + match (data, intern) { + (Data::Unit, InternData::Unit) => true, + (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { + is_dmt_match( + data_model_type, + intern_data_model_type_ref.idx, + idmts, + infs, + ivars, + istrs, + ) + } + (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { + if data_model_types.len() != intern_data_model_group_ref.len { + return false; + } + let mut count = 0; + while count < data_model_types.len() { + let m = is_dmt_match( + data_model_types[count], + count + intern_data_model_group_ref.offset, + idmts, + infs, + ivars, + istrs, + ); + if !m { + return false; + } + count += 1; + } + true + } + (Data::Struct(named_fields), InternData::Struct(intern_named_field_group_ref)) => { + if named_fields.len() != intern_named_field_group_ref.len { + return false; + } + let mut count = 0; + while count < named_fields.len() { + let offct = intern_named_field_group_ref.offset + count; + let inf = &infs[offct]; + if !streq( + named_fields[count].name, + str_subslice(istrs, inf.name.offset, inf.name.len), + ) { + return false; + } + if !is_dmt_match( + named_fields[count].ty, + inf.ty.idx, + idmts, + infs, + ivars, + istrs, + ) { + return false; + } + count += 1; + } + true + } + _ => false, + } + } + + pub const fn is_dmt_match( + dmt: &DataModelType, + idx: usize, + idmts: &[InternDataModelType], + infs: &[InternNamedField], + ivars: &[InternVariant], + istrs: &str, + ) -> bool { + match (idmts[idx], dmt) { + (InternDataModelType::Bool, DataModelType::Bool) => true, + (InternDataModelType::I8, DataModelType::I8) => true, + (InternDataModelType::U8, DataModelType::U8) => true, + (InternDataModelType::I16, DataModelType::I16) => true, + (InternDataModelType::I32, DataModelType::I32) => true, + (InternDataModelType::I64, DataModelType::I64) => true, + (InternDataModelType::I128, DataModelType::I128) => true, + (InternDataModelType::U16, DataModelType::U16) => true, + (InternDataModelType::U32, DataModelType::U32) => true, + (InternDataModelType::U64, DataModelType::U64) => true, + (InternDataModelType::U128, DataModelType::U128) => true, + (InternDataModelType::Usize, DataModelType::Usize) => true, + (InternDataModelType::Isize, DataModelType::Isize) => true, + (InternDataModelType::F32, DataModelType::F32) => true, + (InternDataModelType::F64, DataModelType::F64) => true, + (InternDataModelType::Char, DataModelType::Char) => true, + (InternDataModelType::String, DataModelType::String) => true, + (InternDataModelType::ByteArray, DataModelType::ByteArray) => true, + ( + InternDataModelType::Option(intern_data_model_type_ref), + DataModelType::Option(data_model_type), + ) => is_dmt_match( + data_model_type, + intern_data_model_type_ref.idx, + idmts, + infs, + ivars, + istrs, + ), + (InternDataModelType::Unit, DataModelType::Unit) => true, + ( + InternDataModelType::Seq(intern_data_model_type_ref), + DataModelType::Seq(data_model_type), + ) => is_dmt_match( + data_model_type, + intern_data_model_type_ref.idx, + idmts, + infs, + ivars, + istrs, + ), + ( + InternDataModelType::Tuple(intern_data_model_group_ref), + DataModelType::Tuple(data_model_types), + ) => { + if intern_data_model_group_ref.len != data_model_types.len() { + return false; + } + let mut count = 0; + while count < data_model_types.len() { + let idm = intern_data_model_group_ref.offset + count; + if !is_dmt_match(data_model_types[count], idm, idmts, infs, ivars, istrs) { + return false; + } + count += 1; + } + true + } + ( + InternDataModelType::Array { item, count }, + DataModelType::Array { + item: ditem, + count: dcount, + }, + ) => (count == *dcount) && is_dmt_match(ditem, item.idx, idmts, infs, ivars, istrs), + ( + InternDataModelType::Map { key, val }, + DataModelType::Map { + key: dkey, + val: dval, + }, + ) => { + is_dmt_match(dkey, key.idx, idmts, infs, ivars, istrs) + && is_dmt_match(dval, val.idx, idmts, infs, ivars, istrs) + } + ( + InternDataModelType::Struct { name, data }, + DataModelType::Struct { + name: dname, + data: ddata, + }, + ) => { + let name_match = streq(str_subslice(istrs, name.offset, name.len), dname); + let data_match = is_data_match(ddata, &data, idmts, infs, ivars, istrs); + name_match && data_match + } + ( + InternDataModelType::Enum { name, variants }, + DataModelType::Enum { + name: dname, + variants: dvariants, + }, + ) => { + if !streq(str_subslice(istrs, name.offset, name.len), dname) { + return false; + } + if variants.len != dvariants.len() { + return false; + } + let mut count = 0; + while count < dvariants.len() { + let ivar = &ivars[variants.offset + count]; + if !streq( + dvariants[count].name, + str_subslice(istrs, ivar.name.offset, ivar.name.len), + ) { + return false; + } + if !is_data_match( + &dvariants[count].data, + &ivar.data, + idmts, + infs, + ivars, + istrs, + ) { + return false; + } + count += 1; + } + true + } + (InternDataModelType::Schema, DataModelType::Schema) => todo!(), + _ => false, + } + } + + pub const fn find_run_dmt( + dmts: &[&DataModelType], + idmts: &[InternDataModelType], + infs: &[InternNamedField], + ivars: &[InternVariant], + istrs: &str, + ) -> Option { + if idmts.len() < dmts.len() { + return None; + } + assert!(!dmts.is_empty()); + + let mut count = 0; + 'outer: while count < (idmts.len() - dmts.len()) { + let mut icount = 0; + while icount < dmts.len() { + if !is_dmt_match(dmts[icount], count + icount, idmts, infs, ivars, istrs) { + count += 1; + continue 'outer; + } + icount += 1; + } + return Some(InternDataModelGroupRef { + offset: count, + len: dmts.len(), + }); + } + None + } + + // pub const fn collect_all_run_dmts_data( + // data: &Data, + // ) -> ([InternDataModelType; N], usize) { + // let mut out = [const { InternDataModelType::Schema }; N]; + // let mut ct = 0; + // match data { + // Data::Unit => (out, ct), + // Data::Newtype(data_model_type) => collect_all_run_dmts(data_model_type), + // Data::Tuple(data_model_types) => { + // if let Some(_) = find_run_dmt(data_model_types, &out, infs, ivars, istrs) { + // todo!() + // } else { + // todo!() + // } + // } + // Data::Struct(named_fields) => todo!(), + // } + // } + // pub const fn collect_all_run_dmts( + // dmt: &DataModelType, + // ) -> ([InternDataModelType; N], usize) { + // todo!() + // } + + ////////////////////////////////////////////////////////////////////// + // Named Fields + ////////////////////////////////////////////////////////////////////// + + pub const fn count_named_fields_data(data: &Data) -> usize { + match data { + Data::Unit => 0, + Data::Newtype(data_model_type) => count_named_fields(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_named_fields(data_model_types[idx]); + idx += 1; + } + count + } + Data::Struct(named_fields) => { + let mut count = named_fields.len(); + let mut idx = 0; + while idx < named_fields.len() { + count += count_named_fields(named_fields[idx].ty); + idx += 1; + } + count + } + } + } + + pub const fn count_named_fields(dmt: &DataModelType) -> usize { + match dmt { + DataModelType::Bool => 0, + DataModelType::I8 => 0, + DataModelType::U8 => 0, + DataModelType::I16 => 0, + DataModelType::I32 => 0, + DataModelType::I64 => 0, + DataModelType::I128 => 0, + DataModelType::U16 => 0, + DataModelType::U32 => 0, + DataModelType::U64 => 0, + DataModelType::U128 => 0, + DataModelType::Usize => 0, + DataModelType::Isize => 0, + DataModelType::F32 => 0, + DataModelType::F64 => 0, + DataModelType::Char => 0, + DataModelType::String => 0, + DataModelType::ByteArray => 0, + DataModelType::Option(data_model_type) => count_named_fields(data_model_type), + DataModelType::Unit => 0, + DataModelType::Seq(data_model_type) => count_named_fields(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_named_fields(data_model_types[idx]); + idx += 1; + } + count + } + DataModelType::Array { item, count: _ } => count_named_fields(item), + DataModelType::Map { key, val } => count_named_fields(key) + count_named_fields(val), + DataModelType::Struct { name: _, data } => count_named_fields_data(data), + DataModelType::Enum { name: _, variants } => { + let mut count = 0; + let mut idx = 0; + while idx < variants.len() { + count += count_named_fields_data(&variants[idx].data); + idx += 1; + } + count + } + DataModelType::Schema => todo!(), + } + } + + ////////////////////////////////////////////////////////////////////// + // Variants + ////////////////////////////////////////////////////////////////////// + + pub const fn count_variants_data(data: &Data) -> usize { + match data { + Data::Unit => 0, + Data::Newtype(data_model_type) => count_variants(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_variants(data_model_types[idx]); + idx += 1; + } + count + } + Data::Struct(named_fields) => { + let mut count = 0; + let mut idx = 0; + while idx < named_fields.len() { + count += count_variants(named_fields[idx].ty); + idx += 1; + } + count + } + } + } + + pub const fn count_variants(dmt: &DataModelType) -> usize { + match dmt { + DataModelType::Bool => 0, + DataModelType::I8 => 0, + DataModelType::U8 => 0, + DataModelType::I16 => 0, + DataModelType::I32 => 0, + DataModelType::I64 => 0, + DataModelType::I128 => 0, + DataModelType::U16 => 0, + DataModelType::U32 => 0, + DataModelType::U64 => 0, + DataModelType::U128 => 0, + DataModelType::Usize => 0, + DataModelType::Isize => 0, + DataModelType::F32 => 0, + DataModelType::F64 => 0, + DataModelType::Char => 0, + DataModelType::String => 0, + DataModelType::ByteArray => 0, + DataModelType::Option(data_model_type) => count_variants(data_model_type), + DataModelType::Unit => 0, + DataModelType::Seq(data_model_type) => count_variants(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_variants(data_model_types[idx]); + idx += 1; + } + count + } + DataModelType::Array { item, count: _ } => count_variants(item), + DataModelType::Map { key, val } => count_variants(key) + count_variants(val), + DataModelType::Struct { name: _, data } => count_variants_data(data), + DataModelType::Enum { name: _, variants } => { + let mut count = variants.len(); + let mut idx = 0; + while idx < variants.len() { + count += count_variants_data(&variants[idx].data); + idx += 1; + } + count + } + DataModelType::Schema => todo!(), + } + } + + ////////////////////////////////////////////////////////////////////// + // DMTS + ////////////////////////////////////////////////////////////////////// + + pub const fn count_dmt_data(data: &Data) -> usize { + match data { + Data::Unit => 0, + Data::Newtype(data_model_type) => count_dmt(data_model_type), + Data::Tuple(data_model_types) => { + let mut count = 0; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_dmt(data_model_types[idx]); + idx += 1; + } + count + } + Data::Struct(named_fields) => { + let mut count = 0; + let mut idx = 0; + while idx < named_fields.len() { + count += count_dmt(named_fields[idx].ty); + idx += 1; + } + count + } + } + } + + pub const fn count_dmt(dmt: &DataModelType) -> usize { + match dmt { + DataModelType::Bool => 0, + DataModelType::I8 => 0, + DataModelType::U8 => 0, + DataModelType::I16 => 0, + DataModelType::I32 => 0, + DataModelType::I64 => 0, + DataModelType::I128 => 0, + DataModelType::U16 => 0, + DataModelType::U32 => 0, + DataModelType::U64 => 0, + DataModelType::U128 => 0, + DataModelType::Usize => 0, + DataModelType::Isize => 0, + DataModelType::F32 => 0, + DataModelType::F64 => 0, + DataModelType::Char => 0, + DataModelType::String => 0, + DataModelType::ByteArray => 0, + DataModelType::Option(data_model_type) => 1 + count_dmt(data_model_type), + DataModelType::Unit => 0, + DataModelType::Seq(data_model_type) => 1 + count_dmt(data_model_type), + DataModelType::Tuple(data_model_types) => { + let mut count = 1; + let mut idx = 0; + while idx < data_model_types.len() { + count += count_dmt(data_model_types[idx]); + idx += 1; + } + count + } + DataModelType::Array { item, count: _ } => 1 + count_dmt(item), + DataModelType::Map { key, val } => 1 + count_dmt(key) + count_dmt(val), + DataModelType::Struct { name: _, data } => 1 + count_dmt_data(data), + DataModelType::Enum { name: _, variants } => { + let mut count = 1; + let mut idx = 0; + while idx < variants.len() { + count += count_dmt_data(&variants[idx].data); + idx += 1; + } + count + } + DataModelType::Schema => todo!(), + } + } } pub mod str_intern { diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index 4fe851df..97b4a34b 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -1,5 +1,5 @@ use postcard_schema_ng::{ - schema::{owned::OwnedDataModelType, Data, DataModelType, NamedField, Variant}, sintern, Schema + schema::{intern::ty_intern::count_run_dmts_data, owned::OwnedDataModelType, Data, DataModelType, NamedField, Variant}, sintern, Schema }; use std::{cmp::Ordering, path::PathBuf}; @@ -228,7 +228,15 @@ enum TestEnum2 { fn hacking() { // emit_strings(TestStruct2::SCHEMA); const SINTERN: &str = sintern!(TestStruct2); + const RUN_DMTS: usize = postcard_schema_ng::schema::intern::ty_intern::count_run_dmts(TestStruct2::SCHEMA); + const NFS: usize = postcard_schema_ng::schema::intern::ty_intern::count_named_fields(TestStruct2::SCHEMA); + const VARS: usize = postcard_schema_ng::schema::intern::ty_intern::count_variants(TestStruct2::SCHEMA); + const DMTS: usize = postcard_schema_ng::schema::intern::ty_intern::count_dmt(TestStruct2::SCHEMA); println!("{SINTERN}"); + println!("{RUN_DMTS}"); + println!("{NFS}"); + println!("{VARS}"); + println!("{DMTS}"); panic!("yay"); } From f58130fc52d5120849a4e868a6e4b28856596e90 Mon Sep 17 00:00:00 2001 From: James Munns Date: Fri, 11 Jul 2025 02:02:10 +0200 Subject: [PATCH 4/7] Some progress --- .../postcard-schema-ng/src/schema/intern.rs | 452 +++++++++++++++--- source/postcard-schema-ng/tests/schema.rs | 5 +- 2 files changed, 394 insertions(+), 63 deletions(-) diff --git a/source/postcard-schema-ng/src/schema/intern.rs b/source/postcard-schema-ng/src/schema/intern.rs index 0f504d87..672bb73d 100644 --- a/source/postcard-schema-ng/src/schema/intern.rs +++ b/source/postcard-schema-ng/src/schema/intern.rs @@ -4,7 +4,7 @@ use serde::Serialize; use str_intern::streq; use ty_intern::str_subslice; -use super::{Data, DataModelType}; +use super::{Data, DataModelType, NamedField, Variant}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] pub struct InternStrRef { @@ -216,6 +216,12 @@ pub struct IntermediateSchema< impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: usize> IntermediateSchema<'a, DMTS, RUNDMTS, NFS, VNTS> { + pub const fn blammo(s: &'a str, dmt: &DataModelType) -> Self { + let mut me = Self::new(s); + _ = me.get_or_insert_interned_dmt(dmt); + me + } + const fn new(s: &'a str) -> Self { const NULLSTR: InternStrRef = InternStrRef { offset: 0, len: 0 }; Self { @@ -237,6 +243,184 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: } } + pub const fn get_interned_str(&self, frag: &str) -> InternStrRef { + if frag.len() > self.strs.len() { + panic!() + } + if frag.is_empty() { + panic!(); + } + let strs = self.strs.as_bytes(); + let frag = frag.as_bytes(); + + let mut bi = 0; + 'outer: while bi < (strs.len() - frag.len()) { + if strs[bi] == frag[0] { + let mut off = 1; + while (off < frag.len()) && ((off + bi) < strs.len()) { + if frag[off] != strs[off + bi] { + bi += 1; + continue 'outer; + } + off += 1; + } + return InternStrRef { + offset: bi, + len: frag.len(), + }; + } + bi += 1; + } + panic!() + } + + pub const fn get_or_insert_nf_group( + &mut self, + nfs: &[&NamedField], + ) -> InternNamedFieldGroupRef { + if let Some(nfg) = self.find_named_field_group(nfs) { + return nfg; + } + let mut count = 0; + let start = self.nfs_len; + while count < nfs.len() { + self.nfs[self.nfs_len] = InternNamedField { + name: self.get_interned_str(nfs[count].name), + ty: self.get_or_insert_interned_dmt(nfs[count].ty), + }; + self.nfs_len += 1; + count += 1; + } + InternNamedFieldGroupRef { + offset: start, + len: nfs.len(), + } + } + + pub const fn get_or_insert_variant_group( + &mut self, + vnts: &[&Variant], + ) -> InternVariantGroupRef { + if let Some(vnt) = self.find_variant_group(vnts) { + return vnt; + } + let mut count = 0; + let start = self.vnts_len; + while count < vnts.len() { + self.vnts[self.vnts_len] = InternVariant { + name: self.get_interned_str(vnts[count].name), + data: self.get_or_insert_interned_data(&vnts[count].data), + }; + self.vnts_len += 1; + count += 1; + } + InternVariantGroupRef { + offset: start, + len: vnts.len(), + } + } + + pub const fn get_or_insert_run_dmt( + &mut self, + dmts: &[&DataModelType], + ) -> InternDataModelGroupRef { + if let Some(rdmts) = self.find_run_dmt(dmts) { + return rdmts; + } + let mut count = 0; + let start = self.run_dmts_len; + while count < dmts.len() { + self.run_dmts[self.run_dmts_len] = + self.dmts[self.get_or_insert_interned_dmt(dmts[count]).idx]; + self.run_dmts_len += 1; + count += 1; + } + InternDataModelGroupRef { + offset: start, + len: dmts.len(), + } + } + + pub const fn get_or_insert_interned_data(&mut self, data: &Data) -> InternData { + match data { + Data::Unit => InternData::Unit, + Data::Newtype(data_model_type) => { + let rf = self.get_or_insert_interned_dmt(data_model_type); + InternData::Newtype(rf) + } + Data::Tuple(data_model_types) => { + InternData::Tuple(self.get_or_insert_run_dmt(data_model_types)) + } + Data::Struct(named_fields) => { + InternData::Struct(self.get_or_insert_nf_group(named_fields)) + } + } + } + + pub const fn get_or_insert_interned_dmt( + &mut self, + dmt: &DataModelType, + ) -> InternDataModelTypeRef { + let mut count = 0; + while count < self.dmts().len() { + if self.is_dmt_match(dmt, &self.dmts[count]) { + return InternDataModelTypeRef { idx: count }; + } + count += 1; + } + let old_len = self.dmts_len; + self.dmts[self.dmts_len] = match dmt { + DataModelType::Bool => InternDataModelType::Bool, + DataModelType::I8 => InternDataModelType::I8, + DataModelType::U8 => InternDataModelType::U8, + DataModelType::I16 => InternDataModelType::I16, + DataModelType::I32 => InternDataModelType::I32, + DataModelType::I64 => InternDataModelType::I64, + DataModelType::I128 => InternDataModelType::I128, + DataModelType::U16 => InternDataModelType::U16, + DataModelType::U32 => InternDataModelType::U32, + DataModelType::U64 => InternDataModelType::U64, + DataModelType::U128 => InternDataModelType::U128, + DataModelType::Usize => InternDataModelType::Usize, + DataModelType::Isize => InternDataModelType::Isize, + DataModelType::F32 => InternDataModelType::F32, + DataModelType::F64 => InternDataModelType::F64, + DataModelType::Char => InternDataModelType::Char, + DataModelType::String => InternDataModelType::String, + DataModelType::ByteArray => InternDataModelType::ByteArray, + DataModelType::Option(data_model_type) => { + let rf = self.get_or_insert_interned_dmt(data_model_type); + InternDataModelType::Option(rf) + } + DataModelType::Unit => InternDataModelType::Unit, + DataModelType::Seq(data_model_type) => { + InternDataModelType::Seq(self.get_or_insert_interned_dmt(data_model_type)) + } + DataModelType::Tuple(data_model_types) => { + InternDataModelType::Tuple(self.get_or_insert_run_dmt(data_model_types)) + } + DataModelType::Array { item, count } => InternDataModelType::Array { + item: self.get_or_insert_interned_dmt(item), + count: *count, + }, + DataModelType::Map { key, val } => InternDataModelType::Map { + key: self.get_or_insert_interned_dmt(key), + val: self.get_or_insert_interned_dmt(val), + }, + DataModelType::Struct { name, data } => InternDataModelType::Struct { + name: self.get_interned_str(name), + data: self.get_or_insert_interned_data(data), + }, + DataModelType::Enum { name, variants } => InternDataModelType::Enum { + name: self.get_interned_str(name), + variants: self.get_or_insert_variant_group(variants), + }, + DataModelType::Schema => todo!(), + }; + self.dmts_len += 1; + InternDataModelTypeRef { idx: old_len } + } + const fn run_dmts(&self) -> &[InternDataModelType] { let (now, _later) = self.run_dmts.split_at(self.run_dmts_len); now @@ -448,82 +632,226 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: None } - ////// + pub const fn find_named_field_group( + &self, + nfs: &[&NamedField], + ) -> Option { + if self.nfs.len() < nfs.len() { + return None; + } + assert!(!nfs.is_empty()); - const fn slurp_run_dmts_data(&mut self, data: &Data) { - match data { - Data::Unit => (), - Data::Newtype(data_model_type) => self.slurp_run_dmts(data_model_type), - Data::Tuple(data_model_types) => { - let mut count = 0; - while count < data_model_types.len() { - self.slurp_run_dmts(data_model_types[count]); + let mut count = 0; + 'outer: while count < (self.nfs.len() - nfs.len()) { + let mut icount = 0; + while icount < nfs.len() { + if !streq( + nfs[icount].name, + str_subslice( + self.strs, + self.nfs[count + icount].name.offset, + self.nfs[count + icount].name.len, + ), + ) { count += 1; + continue 'outer; } - todo!() - }, - Data::Struct(named_fields) => { - let mut count = 0; - while count < named_fields.len() { - self.slurp_run_dmts(named_fields[count].ty); + let nfsidx = self.nfs[count + icount].ty.idx; + if !self.is_dmt_match(nfs[icount].ty, &self.dmts()[nfsidx]) { count += 1; + continue 'outer; } - }, + icount += 1; + } + return Some(InternNamedFieldGroupRef { + offset: count, + len: nfs.len(), + }); } + None } - const fn slurp_run_dmts(&mut self, dmt: &DataModelType) { - match dmt { - DataModelType::Bool => {}, - DataModelType::I8 => {}, - DataModelType::U8 => {}, - DataModelType::I16 => {}, - DataModelType::I32 => {}, - DataModelType::I64 => {}, - DataModelType::I128 => {}, - DataModelType::U16 => {}, - DataModelType::U32 => {}, - DataModelType::U64 => {}, - DataModelType::U128 => {}, - DataModelType::Usize => {}, - DataModelType::Isize => {}, - DataModelType::F32 => {}, - DataModelType::F64 => {}, - DataModelType::Char => {}, - DataModelType::String => {}, - DataModelType::ByteArray => {}, - DataModelType::Option(data_model_type) => self.slurp_run_dmts(data_model_type), - DataModelType::Unit => {}, - DataModelType::Seq(data_model_type) => self.slurp_run_dmts(data_model_type), - DataModelType::Tuple(data_model_types) => { - let mut count = 0; - while count < data_model_types.len() { - self.slurp_run_dmts(data_model_types[count]); + pub const fn find_variant_group( + &self, + vnts: &[&Variant], + ) -> Option { + if self.vnts.len() < vnts.len() { + return None; + } + assert!(!vnts.is_empty()); + + let mut count = 0; + 'outer: while count < (self.vnts.len() - vnts.len()) { + let mut icount = 0; + while icount < vnts.len() { + if !streq( + vnts[icount].name, + str_subslice( + self.strs, + self.vnts[count + icount].name.offset, + self.vnts[count + icount].name.len, + ), + ) { count += 1; + continue 'outer; } - if self.find_run_dmt(data_model_types).is_none() { - // one pass over the types to push any subdeps to dmts, then - // a second pass to fill in the run dmts? - todo!() - } - }, - DataModelType::Array { item, count: _ } => self.slurp_run_dmts(item), - DataModelType::Map { key, val } => { - self.slurp_run_dmts(key); - self.slurp_run_dmts(val); - }, - DataModelType::Struct { name: _, data } => self.slurp_run_dmts_data(data), - DataModelType::Enum { name: _, variants } => { - let mut count = 0; - while count < variants.len() { - self.slurp_run_dmts_data(&variants[count].data); + if !self.is_data_match(&vnts[icount].data, &self.vnts[count + icount].data) { count += 1; + continue 'outer; } - }, - DataModelType::Schema => todo!(), + icount += 1; + } + return Some(InternVariantGroupRef { + offset: count, + len: vnts.len(), + }); } + None } + ////// + + // const fn slurp_run_dmts_data(&mut self, data: &Data) { + // match data { + // Data::Unit => (), + // Data::Newtype(data_model_type) => self.slurp_run_dmts(data_model_type), + // Data::Tuple(data_model_types) => { + // let mut count = 0; + // while count < data_model_types.len() { + // self.slurp_run_dmts(data_model_types[count]); + // count += 1; + // } + // todo!() + // } + // Data::Struct(named_fields) => { + // let mut count = 0; + // while count < named_fields.len() { + // self.slurp_run_dmts(named_fields[count].ty); + // count += 1; + // } + // } + // } + // } + + // const fn slurp_non_run_dmts_data(&mut self, data: &Data) { + // match data { + // Data::Unit => {} + // Data::Newtype(data_model_type) => self.slurp_non_run_dmts(data_model_type), + // Data::Tuple(data_model_types) => { + // let mut count = 0; + // while count < data_model_types.len() { + // self.slurp_non_run_dmts(data_model_types[count]); + // count += 1; + // } + // } + // Data::Struct(named_fields) => { + // let mut count = 0; + // while count < named_fields.len() { + // self.slurp_non_run_dmts(named_fields[count].ty); + // count += 1; + // } + // if self.find_named_field_group(named_fields).is_some() { + // return; + // } + // let mut count = 0; + // while count < named_fields.len() {} + // } + // } + // } + + // const fn slurp_non_run_dmts(&mut self, dmt: &DataModelType) { + // match dmt { + // DataModelType::Bool => {} + // DataModelType::I8 => {} + // DataModelType::U8 => {} + // DataModelType::I16 => {} + // DataModelType::I32 => {} + // DataModelType::I64 => {} + // DataModelType::I128 => {} + // DataModelType::U16 => {} + // DataModelType::U32 => {} + // DataModelType::U64 => {} + // DataModelType::U128 => {} + // DataModelType::Usize => {} + // DataModelType::Isize => {} + // DataModelType::F32 => {} + // DataModelType::F64 => {} + // DataModelType::Char => {} + // DataModelType::String => {} + // DataModelType::ByteArray => {} + // DataModelType::Option(data_model_type) => self.slurp_non_run_dmts(data_model_type), + // DataModelType::Unit => {} + // DataModelType::Seq(data_model_type) => self.slurp_non_run_dmts(data_model_type), + // DataModelType::Tuple(data_model_types) => { + // let mut count = 0; + // while count < data_model_types.len() { + // self.slurp_non_run_dmts(data_model_types[count]); + // count += 1; + // } + // } + // DataModelType::Array { item, count } => self.slurp_non_run_dmts(item), + // DataModelType::Map { key, val } => { + // self.slurp_non_run_dmts(key); + // self.slurp_non_run_dmts(val); + // } + // DataModelType::Struct { name, data } => todo!(), + // DataModelType::Enum { name, variants } => todo!(), + // DataModelType::Schema => todo!(), + // } + // } + + // const fn slurp_run_dmts(&mut self, dmt: &DataModelType) { + // match dmt { + // DataModelType::Bool => {} + // DataModelType::I8 => {} + // DataModelType::U8 => {} + // DataModelType::I16 => {} + // DataModelType::I32 => {} + // DataModelType::I64 => {} + // DataModelType::I128 => {} + // DataModelType::U16 => {} + // DataModelType::U32 => {} + // DataModelType::U64 => {} + // DataModelType::U128 => {} + // DataModelType::Usize => {} + // DataModelType::Isize => {} + // DataModelType::F32 => {} + // DataModelType::F64 => {} + // DataModelType::Char => {} + // DataModelType::String => {} + // DataModelType::ByteArray => {} + // DataModelType::Option(data_model_type) => self.slurp_run_dmts(data_model_type), + // DataModelType::Unit => {} + // DataModelType::Seq(data_model_type) => self.slurp_run_dmts(data_model_type), + // DataModelType::Tuple(data_model_types) => { + // let mut count = 0; + // while count < data_model_types.len() { + // self.slurp_run_dmts(data_model_types[count]); + // count += 1; + // } + // if self.find_run_dmt(data_model_types).is_none() { + // // one pass over the types to push any subdeps to dmts, then + // // a second pass to fill in the run dmts? + // todo!() + // } + // } + // DataModelType::Array { item, count: _ } => self.slurp_run_dmts(item), + // DataModelType::Map { key, val } => { + // self.slurp_run_dmts(key); + // self.slurp_run_dmts(val); + // } + // DataModelType::Struct { name: _, data } => self.slurp_run_dmts_data(data), + // DataModelType::Enum { name: _, variants } => { + // let mut count = 0; + // while count < variants.len() { + // self.slurp_run_dmts_data(&variants[count].data); + // count += 1; + // } + // } + // DataModelType::Schema => todo!(), + // } + // } + const fn push_run_dmt(self, dmts: &[&DataModelType]) -> Self { if self.find_run_dmt(dmts).is_some() { return self; diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index 97b4a34b..dc6c6613 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -1,5 +1,5 @@ use postcard_schema_ng::{ - schema::{intern::ty_intern::count_run_dmts_data, owned::OwnedDataModelType, Data, DataModelType, NamedField, Variant}, sintern, Schema + schema::{intern::{ty_intern::count_run_dmts_data, IntermediateSchema}, owned::OwnedDataModelType, Data, DataModelType, NamedField, Variant}, sintern, Schema }; use std::{cmp::Ordering, path::PathBuf}; @@ -237,6 +237,9 @@ fn hacking() { println!("{NFS}"); println!("{VARS}"); println!("{DMTS}"); + + const DENSE: IntermediateSchema = IntermediateSchema::blammo(SINTERN, TestStruct2::SCHEMA); + panic!("yay"); } From 239b33c0e0de41061d1dba46d9a7e3da22f8f260 Mon Sep 17 00:00:00 2001 From: James Munns Date: Fri, 11 Jul 2025 02:28:17 +0200 Subject: [PATCH 5/7] Sort of working --- .../postcard-schema-ng/src/schema/intern.rs | 112 +++++++++++------- source/postcard-schema-ng/tests/schema.rs | 35 ++++++ 2 files changed, 104 insertions(+), 43 deletions(-) diff --git a/source/postcard-schema-ng/src/schema/intern.rs b/source/postcard-schema-ng/src/schema/intern.rs index 672bb73d..25646dad 100644 --- a/source/postcard-schema-ng/src/schema/intern.rs +++ b/source/postcard-schema-ng/src/schema/intern.rs @@ -1,6 +1,6 @@ #![allow(missing_docs, dead_code)] -use serde::Serialize; +use serde::{ser::SerializeStruct, Serialize}; use str_intern::streq; use ty_intern::str_subslice; @@ -191,6 +191,7 @@ pub struct InternVariant { pub data: InternData, } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct IntermediateSchema< 'a, const DMTS: usize, @@ -213,6 +214,37 @@ pub struct IntermediateSchema< vnts_len: usize, } +impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: usize> Serialize + for IntermediateSchema<'a, DMTS, RUNDMTS, NFS, VNTS> +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut s = serializer.serialize_struct("IntermediateSchema", 5)?; + s.serialize_field("strs", self.strs)?; + s.serialize_field("run_dmts", self.run_dmts())?; + s.serialize_field("dmts", self.dmts())?; + s.serialize_field("nfs", self.nfs())?; + s.serialize_field("vnts", self.vnts())?; + s.end() + } +} + +impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: usize> + core::fmt::Debug for IntermediateSchema<'a, DMTS, RUNDMTS, NFS, VNTS> +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("IntermediateSchema") + .field("run_dmts", &self.run_dmts()) + .field("dmts", &self.dmts()) + .field("nfs", &self.nfs()) + .field("vnts", &self.vnts()) + .field("strs", &self.strs) + .finish() + } +} + impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: usize> IntermediateSchema<'a, DMTS, RUNDMTS, NFS, VNTS> { @@ -254,22 +286,19 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: let frag = frag.as_bytes(); let mut bi = 0; - 'outer: while bi < (strs.len() - frag.len()) { - if strs[bi] == frag[0] { - let mut off = 1; - while (off < frag.len()) && ((off + bi) < strs.len()) { - if frag[off] != strs[off + bi] { - bi += 1; - continue 'outer; - } - off += 1; + 'outer: while bi <= (strs.len() - frag.len()) { + let mut off = 0; + while (off < frag.len()) && ((off + bi) < strs.len()) { + if frag[off] != strs[off + bi] { + bi += 1; + continue 'outer; } - return InternStrRef { - offset: bi, - len: frag.len(), - }; + off += 1; } - bi += 1; + return InternStrRef { + offset: bi, + len: frag.len(), + }; } panic!() } @@ -671,10 +700,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: None } - pub const fn find_variant_group( - &self, - vnts: &[&Variant], - ) -> Option { + pub const fn find_variant_group(&self, vnts: &[&Variant]) -> Option { if self.vnts.len() < vnts.len() { return None; } @@ -1393,10 +1419,10 @@ pub mod ty_intern { pub const fn count_dmt_data(data: &Data) -> usize { match data { - Data::Unit => 0, - Data::Newtype(data_model_type) => count_dmt(data_model_type), + Data::Unit => 1, + Data::Newtype(data_model_type) => 1 + count_dmt(data_model_type), Data::Tuple(data_model_types) => { - let mut count = 0; + let mut count = 1 + data_model_types.len(); let mut idx = 0; while idx < data_model_types.len() { count += count_dmt(data_model_types[idx]); @@ -1405,7 +1431,7 @@ pub mod ty_intern { count } Data::Struct(named_fields) => { - let mut count = 0; + let mut count = 1; let mut idx = 0; while idx < named_fields.len() { count += count_dmt(named_fields[idx].ty); @@ -1418,29 +1444,29 @@ pub mod ty_intern { pub const fn count_dmt(dmt: &DataModelType) -> usize { match dmt { - DataModelType::Bool => 0, - DataModelType::I8 => 0, - DataModelType::U8 => 0, - DataModelType::I16 => 0, - DataModelType::I32 => 0, - DataModelType::I64 => 0, - DataModelType::I128 => 0, - DataModelType::U16 => 0, - DataModelType::U32 => 0, - DataModelType::U64 => 0, - DataModelType::U128 => 0, - DataModelType::Usize => 0, - DataModelType::Isize => 0, - DataModelType::F32 => 0, - DataModelType::F64 => 0, - DataModelType::Char => 0, - DataModelType::String => 0, - DataModelType::ByteArray => 0, + DataModelType::Bool => 1, + DataModelType::I8 => 1, + DataModelType::U8 => 1, + DataModelType::I16 => 1, + DataModelType::I32 => 1, + DataModelType::I64 => 1, + DataModelType::I128 => 1, + DataModelType::U16 => 1, + DataModelType::U32 => 1, + DataModelType::U64 => 1, + DataModelType::U128 => 1, + DataModelType::Usize => 1, + DataModelType::Isize => 1, + DataModelType::F32 => 1, + DataModelType::F64 => 1, + DataModelType::Char => 1, + DataModelType::String => 1, + DataModelType::ByteArray => 1, DataModelType::Option(data_model_type) => 1 + count_dmt(data_model_type), - DataModelType::Unit => 0, + DataModelType::Unit => 1, DataModelType::Seq(data_model_type) => 1 + count_dmt(data_model_type), DataModelType::Tuple(data_model_types) => { - let mut count = 1; + let mut count = 1 + data_model_types.len(); let mut idx = 0; while idx < data_model_types.len() { count += count_dmt(data_model_types[idx]); diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index dc6c6613..1a765401 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -224,6 +224,33 @@ enum TestEnum2 { Tup(u64, bool), } +#[test] +fn hacking3() { + // emit_strings(TestStruct2::SCHEMA); + const SINTERN: &str = sintern!(TestStruct3); + const RUN_DMTS: usize = postcard_schema_ng::schema::intern::ty_intern::count_run_dmts(TestStruct3::SCHEMA); + const NFS: usize = postcard_schema_ng::schema::intern::ty_intern::count_named_fields(TestStruct3::SCHEMA); + const VARS: usize = postcard_schema_ng::schema::intern::ty_intern::count_variants(TestStruct3::SCHEMA); + const DMTS: usize = postcard_schema_ng::schema::intern::ty_intern::count_dmt(TestStruct3::SCHEMA); + println!("{SINTERN}"); + println!("{RUN_DMTS}"); + println!("{NFS}"); + println!("{VARS}"); + println!("{DMTS}"); + + const DENSE: IntermediateSchema = IntermediateSchema::blammo(SINTERN, TestStruct3::SCHEMA); + // const DENSE: IntermediateSchema<100, 100, 100, 100> = IntermediateSchema::blammo(SINTERN, TestStruct3::SCHEMA); + println!("{DENSE:#?}"); + let ser = postcard::to_stdvec(&DENSE).unwrap(); + println!("{ser:02X?}"); + println!("{}", ser.len()); + let ser = postcard::to_stdvec(TestStruct3::SCHEMA).unwrap(); + println!("{ser:02X?}"); + println!("{}", ser.len()); + + panic!("yay"); +} + #[test] fn hacking() { // emit_strings(TestStruct2::SCHEMA); @@ -239,6 +266,14 @@ fn hacking() { println!("{DMTS}"); const DENSE: IntermediateSchema = IntermediateSchema::blammo(SINTERN, TestStruct2::SCHEMA); + // const DENSE: IntermediateSchema<100, 100, 100, 100> = IntermediateSchema::blammo(SINTERN, TestStruct2::SCHEMA); + println!("{DENSE:#?}"); + let ser = postcard::to_stdvec(&DENSE).unwrap(); + println!("{ser:02X?}"); + println!("{}", ser.len()); + let ser = postcard::to_stdvec(TestStruct2::SCHEMA).unwrap(); + println!("{ser:02X?}"); + println!("{}", ser.len()); panic!("yay"); } From 74e382eccc19b68c0a0c496632c738c88b0fc78a Mon Sep 17 00:00:00 2001 From: James Munns Date: Fri, 11 Jul 2025 03:08:40 +0200 Subject: [PATCH 6/7] Seems to mostly work, results are unfortunately mixed. --- .../postcard-schema-ng/src/schema/intern.rs | 654 ++++++++++-------- source/postcard-schema-ng/tests/schema.rs | 31 + 2 files changed, 415 insertions(+), 270 deletions(-) diff --git a/source/postcard-schema-ng/src/schema/intern.rs b/source/postcard-schema-ng/src/schema/intern.rs index 25646dad..360101e5 100644 --- a/source/postcard-schema-ng/src/schema/intern.rs +++ b/source/postcard-schema-ng/src/schema/intern.rs @@ -13,8 +13,68 @@ pub struct InternStrRef { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub struct InternDataModelTypeRef { - idx: usize, +pub enum InternDataModelTypeRef { + /// The `bool` Serde Data Model Type + Bool, + + /// The `i8` Serde Data Model Type + I8, + + /// The `u8` Serde Data Model Type + U8, + + /// A variably encoded i16 + I16, + + /// A variably encoded i32 + I32, + + /// A variably encoded i64 + I64, + + /// A variably encoded i128 + I128, + + /// A variably encoded u16 + U16, + + /// A variably encoded u32 + U32, + + /// A variably encoded u64 + U64, + + /// A variably encoded u128 + U128, + + /// A variably encoded usize + Usize, + + /// A variably encoded isize + Isize, + + /// The `f32` Serde Data Model Type + F32, + + /// The `f64` Serde Data Model Type + F64, + + /// The `char` Serde Data Model Type + Char, + + /// The `String` Serde Data Model Type + String, + + /// The `&[u8]` Serde Data Model Type + ByteArray, + + /// The `()` Serde Data Model Type + Unit, + + Ref(usize), + + /// A [`DataModelType`]/[`OwnedDataModelType`](owned::OwnedDataModelType) + Schema, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] @@ -264,7 +324,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: dmts_len: 0, nfs: [InternNamedField { name: NULLSTR, - ty: InternDataModelTypeRef { idx: 0 }, + ty: InternDataModelTypeRef::Schema, }; NFS], nfs_len: 0, vnts: [InternVariant { @@ -359,8 +419,8 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: let mut count = 0; let start = self.run_dmts_len; while count < dmts.len() { - self.run_dmts[self.run_dmts_len] = - self.dmts[self.get_or_insert_interned_dmt(dmts[count]).idx]; + let dr = self.get_or_insert_interned_dmt(dmts[count]); + self.run_dmts[self.run_dmts_len] = self.dmt_from_ref(&dr); self.run_dmts_len += 1; count += 1; } @@ -390,38 +450,62 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: &mut self, dmt: &DataModelType, ) -> InternDataModelTypeRef { + match dmt { + DataModelType::Bool => return InternDataModelTypeRef::Bool, + DataModelType::I8 => return InternDataModelTypeRef::I8, + DataModelType::U8 => return InternDataModelTypeRef::U8, + DataModelType::I16 => return InternDataModelTypeRef::I16, + DataModelType::I32 => return InternDataModelTypeRef::I32, + DataModelType::I64 => return InternDataModelTypeRef::I64, + DataModelType::I128 => return InternDataModelTypeRef::I128, + DataModelType::U16 => return InternDataModelTypeRef::U16, + DataModelType::U32 => return InternDataModelTypeRef::U32, + DataModelType::U64 => return InternDataModelTypeRef::U64, + DataModelType::U128 => return InternDataModelTypeRef::U128, + DataModelType::Usize => return InternDataModelTypeRef::Usize, + DataModelType::Isize => return InternDataModelTypeRef::Isize, + DataModelType::F32 => return InternDataModelTypeRef::F32, + DataModelType::F64 => return InternDataModelTypeRef::F64, + DataModelType::Char => return InternDataModelTypeRef::Char, + DataModelType::String => return InternDataModelTypeRef::String, + DataModelType::ByteArray => return InternDataModelTypeRef::ByteArray, + DataModelType::Unit => return InternDataModelTypeRef::Unit, + _ => {} + } + + let mut count = 0; while count < self.dmts().len() { if self.is_dmt_match(dmt, &self.dmts[count]) { - return InternDataModelTypeRef { idx: count }; + return InternDataModelTypeRef::Ref(count); } count += 1; } let old_len = self.dmts_len; self.dmts[self.dmts_len] = match dmt { - DataModelType::Bool => InternDataModelType::Bool, - DataModelType::I8 => InternDataModelType::I8, - DataModelType::U8 => InternDataModelType::U8, - DataModelType::I16 => InternDataModelType::I16, - DataModelType::I32 => InternDataModelType::I32, - DataModelType::I64 => InternDataModelType::I64, - DataModelType::I128 => InternDataModelType::I128, - DataModelType::U16 => InternDataModelType::U16, - DataModelType::U32 => InternDataModelType::U32, - DataModelType::U64 => InternDataModelType::U64, - DataModelType::U128 => InternDataModelType::U128, - DataModelType::Usize => InternDataModelType::Usize, - DataModelType::Isize => InternDataModelType::Isize, - DataModelType::F32 => InternDataModelType::F32, - DataModelType::F64 => InternDataModelType::F64, - DataModelType::Char => InternDataModelType::Char, - DataModelType::String => InternDataModelType::String, - DataModelType::ByteArray => InternDataModelType::ByteArray, + DataModelType::Bool => unreachable!(), + DataModelType::I8 => unreachable!(), + DataModelType::U8 => unreachable!(), + DataModelType::I16 => unreachable!(), + DataModelType::I32 => unreachable!(), + DataModelType::I64 => unreachable!(), + DataModelType::I128 => unreachable!(), + DataModelType::U16 => unreachable!(), + DataModelType::U32 => unreachable!(), + DataModelType::U64 => unreachable!(), + DataModelType::U128 => unreachable!(), + DataModelType::Usize => unreachable!(), + DataModelType::Isize => unreachable!(), + DataModelType::F32 => unreachable!(), + DataModelType::F64 => unreachable!(), + DataModelType::Char => unreachable!(), + DataModelType::String => unreachable!(), + DataModelType::ByteArray => unreachable!(), + DataModelType::Unit => unreachable!(), DataModelType::Option(data_model_type) => { let rf = self.get_or_insert_interned_dmt(data_model_type); InternDataModelType::Option(rf) } - DataModelType::Unit => InternDataModelType::Unit, DataModelType::Seq(data_model_type) => { InternDataModelType::Seq(self.get_or_insert_interned_dmt(data_model_type)) } @@ -447,7 +531,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: DataModelType::Schema => todo!(), }; self.dmts_len += 1; - InternDataModelTypeRef { idx: old_len } + InternDataModelTypeRef::Ref(old_len) } const fn run_dmts(&self) -> &[InternDataModelType] { @@ -476,9 +560,11 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: match (data, intern) { (Data::Unit, InternData::Unit) => true, (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { + let data = self.dmt_from_ref(intern_data_model_type_ref); + self.is_dmt_match( data_model_type, - &self.dmts()[intern_data_model_type_ref.idx], + &data, ) } (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { @@ -512,7 +598,10 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: ) { return false; } - if !self.is_dmt_match(named_fields[count].ty, &self.dmts()[inf.ty.idx]) { + + let data = self.dmt_from_ref(&inf.ty); + + if !self.is_dmt_match(named_fields[count].ty, &data) { return false; } count += 1; @@ -523,6 +612,32 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: } } + pub const fn dmt_from_ref(&self, dref: &InternDataModelTypeRef) -> InternDataModelType { + match dref { + InternDataModelTypeRef::Bool => InternDataModelType::Bool, + InternDataModelTypeRef::I8 => InternDataModelType::I8, + InternDataModelTypeRef::U8 => InternDataModelType::U8, + InternDataModelTypeRef::I16 => InternDataModelType::I16, + InternDataModelTypeRef::I32 => InternDataModelType::I32, + InternDataModelTypeRef::I64 => InternDataModelType::I64, + InternDataModelTypeRef::I128 => InternDataModelType::I128, + InternDataModelTypeRef::U16 => InternDataModelType::U16, + InternDataModelTypeRef::U32 => InternDataModelType::U32, + InternDataModelTypeRef::U64 => InternDataModelType::U64, + InternDataModelTypeRef::U128 => InternDataModelType::U128, + InternDataModelTypeRef::Usize => InternDataModelType::Usize, + InternDataModelTypeRef::Isize => InternDataModelType::Isize, + InternDataModelTypeRef::F32 => InternDataModelType::F32, + InternDataModelTypeRef::F64 => InternDataModelType::F64, + InternDataModelTypeRef::Char => InternDataModelType::Char, + InternDataModelTypeRef::String => InternDataModelType::String, + InternDataModelTypeRef::ByteArray => InternDataModelType::ByteArray, + InternDataModelTypeRef::Unit => InternDataModelType::Unit, + InternDataModelTypeRef::Ref(idx) => self.dmts()[*idx], + InternDataModelTypeRef::Schema => todo!(), + } + } + pub const fn is_dmt_match(&self, dmt: &DataModelType, idmt: &InternDataModelType) -> bool { match (idmt, dmt) { (InternDataModelType::Bool, DataModelType::Bool) => true, @@ -548,7 +663,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: DataModelType::Option(data_model_type), ) => self.is_dmt_match( data_model_type, - &self.dmts()[intern_data_model_type_ref.idx], + &self.dmt_from_ref(intern_data_model_type_ref), ), (InternDataModelType::Unit, DataModelType::Unit) => true, ( @@ -556,7 +671,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: DataModelType::Seq(data_model_type), ) => self.is_dmt_match( data_model_type, - &self.dmts()[intern_data_model_type_ref.idx], + &self.dmt_from_ref(intern_data_model_type_ref), ), ( InternDataModelType::Tuple(intern_data_model_group_ref), @@ -581,7 +696,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: item: ditem, count: dcount, }, - ) => (*count == *dcount) && self.is_dmt_match(ditem, &self.dmts()[item.idx]), + ) => (*count == *dcount) && self.is_dmt_match(ditem, &self.dmt_from_ref(item)), ( InternDataModelType::Map { key, val }, DataModelType::Map { @@ -589,8 +704,8 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: val: dval, }, ) => { - self.is_dmt_match(dkey, &self.dmts()[key.idx]) - && self.is_dmt_match(dval, &self.dmts()[val.idx]) + self.is_dmt_match(dkey, &self.dmt_from_ref(key)) + && self.is_dmt_match(dval, &self.dmt_from_ref(val)) } ( InternDataModelType::Struct { name, data }, @@ -685,8 +800,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: count += 1; continue 'outer; } - let nfsidx = self.nfs[count + icount].ty.idx; - if !self.is_dmt_match(nfs[icount].ty, &self.dmts()[nfsidx]) { + if !self.is_dmt_match(nfs[icount].ty, &self.dmt_from_ref(&self.nfs[count + icount].ty)) { count += 1; continue 'outer; } @@ -996,244 +1110,244 @@ pub mod ty_intern { } } - pub const fn is_data_match( - data: &Data, - intern: &InternData, - idmts: &[InternDataModelType], - infs: &[InternNamedField], - ivars: &[InternVariant], - istrs: &str, - ) -> bool { - match (data, intern) { - (Data::Unit, InternData::Unit) => true, - (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { - is_dmt_match( - data_model_type, - intern_data_model_type_ref.idx, - idmts, - infs, - ivars, - istrs, - ) - } - (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { - if data_model_types.len() != intern_data_model_group_ref.len { - return false; - } - let mut count = 0; - while count < data_model_types.len() { - let m = is_dmt_match( - data_model_types[count], - count + intern_data_model_group_ref.offset, - idmts, - infs, - ivars, - istrs, - ); - if !m { - return false; - } - count += 1; - } - true - } - (Data::Struct(named_fields), InternData::Struct(intern_named_field_group_ref)) => { - if named_fields.len() != intern_named_field_group_ref.len { - return false; - } - let mut count = 0; - while count < named_fields.len() { - let offct = intern_named_field_group_ref.offset + count; - let inf = &infs[offct]; - if !streq( - named_fields[count].name, - str_subslice(istrs, inf.name.offset, inf.name.len), - ) { - return false; - } - if !is_dmt_match( - named_fields[count].ty, - inf.ty.idx, - idmts, - infs, - ivars, - istrs, - ) { - return false; - } - count += 1; - } - true - } - _ => false, - } - } + // pub const fn is_data_match( + // data: &Data, + // intern: &InternData, + // idmts: &[InternDataModelType], + // infs: &[InternNamedField], + // ivars: &[InternVariant], + // istrs: &str, + // ) -> bool { + // match (data, intern) { + // (Data::Unit, InternData::Unit) => true, + // (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { + // is_dmt_match( + // data_model_type, + // intern_data_model_type_ref.idx, + // idmts, + // infs, + // ivars, + // istrs, + // ) + // } + // (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { + // if data_model_types.len() != intern_data_model_group_ref.len { + // return false; + // } + // let mut count = 0; + // while count < data_model_types.len() { + // let m = is_dmt_match( + // data_model_types[count], + // count + intern_data_model_group_ref.offset, + // idmts, + // infs, + // ivars, + // istrs, + // ); + // if !m { + // return false; + // } + // count += 1; + // } + // true + // } + // (Data::Struct(named_fields), InternData::Struct(intern_named_field_group_ref)) => { + // if named_fields.len() != intern_named_field_group_ref.len { + // return false; + // } + // let mut count = 0; + // while count < named_fields.len() { + // let offct = intern_named_field_group_ref.offset + count; + // let inf = &infs[offct]; + // if !streq( + // named_fields[count].name, + // str_subslice(istrs, inf.name.offset, inf.name.len), + // ) { + // return false; + // } + // if !is_dmt_match( + // named_fields[count].ty, + // inf.ty.idx, + // idmts, + // infs, + // ivars, + // istrs, + // ) { + // return false; + // } + // count += 1; + // } + // true + // } + // _ => false, + // } + // } - pub const fn is_dmt_match( - dmt: &DataModelType, - idx: usize, - idmts: &[InternDataModelType], - infs: &[InternNamedField], - ivars: &[InternVariant], - istrs: &str, - ) -> bool { - match (idmts[idx], dmt) { - (InternDataModelType::Bool, DataModelType::Bool) => true, - (InternDataModelType::I8, DataModelType::I8) => true, - (InternDataModelType::U8, DataModelType::U8) => true, - (InternDataModelType::I16, DataModelType::I16) => true, - (InternDataModelType::I32, DataModelType::I32) => true, - (InternDataModelType::I64, DataModelType::I64) => true, - (InternDataModelType::I128, DataModelType::I128) => true, - (InternDataModelType::U16, DataModelType::U16) => true, - (InternDataModelType::U32, DataModelType::U32) => true, - (InternDataModelType::U64, DataModelType::U64) => true, - (InternDataModelType::U128, DataModelType::U128) => true, - (InternDataModelType::Usize, DataModelType::Usize) => true, - (InternDataModelType::Isize, DataModelType::Isize) => true, - (InternDataModelType::F32, DataModelType::F32) => true, - (InternDataModelType::F64, DataModelType::F64) => true, - (InternDataModelType::Char, DataModelType::Char) => true, - (InternDataModelType::String, DataModelType::String) => true, - (InternDataModelType::ByteArray, DataModelType::ByteArray) => true, - ( - InternDataModelType::Option(intern_data_model_type_ref), - DataModelType::Option(data_model_type), - ) => is_dmt_match( - data_model_type, - intern_data_model_type_ref.idx, - idmts, - infs, - ivars, - istrs, - ), - (InternDataModelType::Unit, DataModelType::Unit) => true, - ( - InternDataModelType::Seq(intern_data_model_type_ref), - DataModelType::Seq(data_model_type), - ) => is_dmt_match( - data_model_type, - intern_data_model_type_ref.idx, - idmts, - infs, - ivars, - istrs, - ), - ( - InternDataModelType::Tuple(intern_data_model_group_ref), - DataModelType::Tuple(data_model_types), - ) => { - if intern_data_model_group_ref.len != data_model_types.len() { - return false; - } - let mut count = 0; - while count < data_model_types.len() { - let idm = intern_data_model_group_ref.offset + count; - if !is_dmt_match(data_model_types[count], idm, idmts, infs, ivars, istrs) { - return false; - } - count += 1; - } - true - } - ( - InternDataModelType::Array { item, count }, - DataModelType::Array { - item: ditem, - count: dcount, - }, - ) => (count == *dcount) && is_dmt_match(ditem, item.idx, idmts, infs, ivars, istrs), - ( - InternDataModelType::Map { key, val }, - DataModelType::Map { - key: dkey, - val: dval, - }, - ) => { - is_dmt_match(dkey, key.idx, idmts, infs, ivars, istrs) - && is_dmt_match(dval, val.idx, idmts, infs, ivars, istrs) - } - ( - InternDataModelType::Struct { name, data }, - DataModelType::Struct { - name: dname, - data: ddata, - }, - ) => { - let name_match = streq(str_subslice(istrs, name.offset, name.len), dname); - let data_match = is_data_match(ddata, &data, idmts, infs, ivars, istrs); - name_match && data_match - } - ( - InternDataModelType::Enum { name, variants }, - DataModelType::Enum { - name: dname, - variants: dvariants, - }, - ) => { - if !streq(str_subslice(istrs, name.offset, name.len), dname) { - return false; - } - if variants.len != dvariants.len() { - return false; - } - let mut count = 0; - while count < dvariants.len() { - let ivar = &ivars[variants.offset + count]; - if !streq( - dvariants[count].name, - str_subslice(istrs, ivar.name.offset, ivar.name.len), - ) { - return false; - } - if !is_data_match( - &dvariants[count].data, - &ivar.data, - idmts, - infs, - ivars, - istrs, - ) { - return false; - } - count += 1; - } - true - } - (InternDataModelType::Schema, DataModelType::Schema) => todo!(), - _ => false, - } - } + // pub const fn is_dmt_match( + // dmt: &DataModelType, + // idx: usize, + // idmts: &[InternDataModelType], + // infs: &[InternNamedField], + // ivars: &[InternVariant], + // istrs: &str, + // ) -> bool { + // match (idmts[idx], dmt) { + // (InternDataModelType::Bool, DataModelType::Bool) => true, + // (InternDataModelType::I8, DataModelType::I8) => true, + // (InternDataModelType::U8, DataModelType::U8) => true, + // (InternDataModelType::I16, DataModelType::I16) => true, + // (InternDataModelType::I32, DataModelType::I32) => true, + // (InternDataModelType::I64, DataModelType::I64) => true, + // (InternDataModelType::I128, DataModelType::I128) => true, + // (InternDataModelType::U16, DataModelType::U16) => true, + // (InternDataModelType::U32, DataModelType::U32) => true, + // (InternDataModelType::U64, DataModelType::U64) => true, + // (InternDataModelType::U128, DataModelType::U128) => true, + // (InternDataModelType::Usize, DataModelType::Usize) => true, + // (InternDataModelType::Isize, DataModelType::Isize) => true, + // (InternDataModelType::F32, DataModelType::F32) => true, + // (InternDataModelType::F64, DataModelType::F64) => true, + // (InternDataModelType::Char, DataModelType::Char) => true, + // (InternDataModelType::String, DataModelType::String) => true, + // (InternDataModelType::ByteArray, DataModelType::ByteArray) => true, + // ( + // InternDataModelType::Option(intern_data_model_type_ref), + // DataModelType::Option(data_model_type), + // ) => is_dmt_match( + // data_model_type, + // intern_data_model_type_ref.idx, + // idmts, + // infs, + // ivars, + // istrs, + // ), + // (InternDataModelType::Unit, DataModelType::Unit) => true, + // ( + // InternDataModelType::Seq(intern_data_model_type_ref), + // DataModelType::Seq(data_model_type), + // ) => is_dmt_match( + // data_model_type, + // intern_data_model_type_ref.idx, + // idmts, + // infs, + // ivars, + // istrs, + // ), + // ( + // InternDataModelType::Tuple(intern_data_model_group_ref), + // DataModelType::Tuple(data_model_types), + // ) => { + // if intern_data_model_group_ref.len != data_model_types.len() { + // return false; + // } + // let mut count = 0; + // while count < data_model_types.len() { + // let idm = intern_data_model_group_ref.offset + count; + // if !is_dmt_match(data_model_types[count], idm, idmts, infs, ivars, istrs) { + // return false; + // } + // count += 1; + // } + // true + // } + // ( + // InternDataModelType::Array { item, count }, + // DataModelType::Array { + // item: ditem, + // count: dcount, + // }, + // ) => (count == *dcount) && is_dmt_match(ditem, item.idx, idmts, infs, ivars, istrs), + // ( + // InternDataModelType::Map { key, val }, + // DataModelType::Map { + // key: dkey, + // val: dval, + // }, + // ) => { + // is_dmt_match(dkey, key.idx, idmts, infs, ivars, istrs) + // && is_dmt_match(dval, val.idx, idmts, infs, ivars, istrs) + // } + // ( + // InternDataModelType::Struct { name, data }, + // DataModelType::Struct { + // name: dname, + // data: ddata, + // }, + // ) => { + // let name_match = streq(str_subslice(istrs, name.offset, name.len), dname); + // let data_match = is_data_match(ddata, &data, idmts, infs, ivars, istrs); + // name_match && data_match + // } + // ( + // InternDataModelType::Enum { name, variants }, + // DataModelType::Enum { + // name: dname, + // variants: dvariants, + // }, + // ) => { + // if !streq(str_subslice(istrs, name.offset, name.len), dname) { + // return false; + // } + // if variants.len != dvariants.len() { + // return false; + // } + // let mut count = 0; + // while count < dvariants.len() { + // let ivar = &ivars[variants.offset + count]; + // if !streq( + // dvariants[count].name, + // str_subslice(istrs, ivar.name.offset, ivar.name.len), + // ) { + // return false; + // } + // if !is_data_match( + // &dvariants[count].data, + // &ivar.data, + // idmts, + // infs, + // ivars, + // istrs, + // ) { + // return false; + // } + // count += 1; + // } + // true + // } + // (InternDataModelType::Schema, DataModelType::Schema) => todo!(), + // _ => false, + // } + // } - pub const fn find_run_dmt( - dmts: &[&DataModelType], - idmts: &[InternDataModelType], - infs: &[InternNamedField], - ivars: &[InternVariant], - istrs: &str, - ) -> Option { - if idmts.len() < dmts.len() { - return None; - } - assert!(!dmts.is_empty()); + // pub const fn find_run_dmt( + // dmts: &[&DataModelType], + // idmts: &[InternDataModelType], + // infs: &[InternNamedField], + // ivars: &[InternVariant], + // istrs: &str, + // ) -> Option { + // if idmts.len() < dmts.len() { + // return None; + // } + // assert!(!dmts.is_empty()); - let mut count = 0; - 'outer: while count < (idmts.len() - dmts.len()) { - let mut icount = 0; - while icount < dmts.len() { - if !is_dmt_match(dmts[icount], count + icount, idmts, infs, ivars, istrs) { - count += 1; - continue 'outer; - } - icount += 1; - } - return Some(InternDataModelGroupRef { - offset: count, - len: dmts.len(), - }); - } - None - } + // let mut count = 0; + // 'outer: while count < (idmts.len() - dmts.len()) { + // let mut icount = 0; + // while icount < dmts.len() { + // if !is_dmt_match(dmts[icount], count + icount, idmts, infs, ivars, istrs) { + // count += 1; + // continue 'outer; + // } + // icount += 1; + // } + // return Some(InternDataModelGroupRef { + // offset: count, + // len: dmts.len(), + // }); + // } + // None + // } // pub const fn collect_all_run_dmts_data( // data: &Data, diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index 1a765401..c819c0f4 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -182,7 +182,11 @@ struct TestStruct1 { struct TestStruct2<'a> { w: (u8, u16, u32), x: TestEnum<'a>, + xa: TestEnum<'a>, + xb: TestEnum<'a>, y: TestStruct1, + ya: TestStruct1, + yb: TestStruct1, z: Result, } @@ -224,6 +228,33 @@ enum TestEnum2 { Tup(u64, bool), } +#[test] +fn hacking4() { + // emit_strings(TestStruct2::SCHEMA); + const SINTERN: &str = sintern!(TestEnum); + const RUN_DMTS: usize = postcard_schema_ng::schema::intern::ty_intern::count_run_dmts(TestEnum::SCHEMA); + const NFS: usize = postcard_schema_ng::schema::intern::ty_intern::count_named_fields(TestEnum::SCHEMA); + const VARS: usize = postcard_schema_ng::schema::intern::ty_intern::count_variants(TestEnum::SCHEMA); + const DMTS: usize = postcard_schema_ng::schema::intern::ty_intern::count_dmt(TestEnum::SCHEMA); + println!("{SINTERN}"); + println!("{RUN_DMTS}"); + println!("{NFS}"); + println!("{VARS}"); + println!("{DMTS}"); + + const DENSE: IntermediateSchema = IntermediateSchema::blammo(SINTERN, TestEnum::SCHEMA); + // const DENSE: IntermediateSchema<100, 100, 100, 100> = IntermediateSchema::blammo(SINTERN, TestEnum::SCHEMA); + println!("{DENSE:#?}"); + let ser = postcard::to_stdvec(&DENSE).unwrap(); + println!("{ser:02X?}"); + println!("{}", ser.len()); + let ser = postcard::to_stdvec(TestEnum::SCHEMA).unwrap(); + println!("{ser:02X?}"); + println!("{}", ser.len()); + + panic!("yay"); +} + #[test] fn hacking3() { // emit_strings(TestStruct2::SCHEMA); From 8ef9e572b600a4295d040ab54e3ff5ef0fc86afd Mon Sep 17 00:00:00 2001 From: James Munns Date: Fri, 11 Jul 2025 12:25:16 +0200 Subject: [PATCH 7/7] Remove some dead code --- .../postcard-schema-ng/src/schema/intern.rs | 432 +----------------- source/postcard-schema-ng/tests/schema.rs | 3 - 2 files changed, 5 insertions(+), 430 deletions(-) diff --git a/source/postcard-schema-ng/src/schema/intern.rs b/source/postcard-schema-ng/src/schema/intern.rs index 360101e5..f45ed871 100644 --- a/source/postcard-schema-ng/src/schema/intern.rs +++ b/source/postcard-schema-ng/src/schema/intern.rs @@ -473,7 +473,6 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: _ => {} } - let mut count = 0; while count < self.dmts().len() { if self.is_dmt_match(dmt, &self.dmts[count]) { @@ -562,10 +561,7 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { let data = self.dmt_from_ref(intern_data_model_type_ref); - self.is_dmt_match( - data_model_type, - &data, - ) + self.is_dmt_match(data_model_type, &data) } (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { if data_model_types.len() != intern_data_model_group_ref.len { @@ -800,7 +796,10 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: count += 1; continue 'outer; } - if !self.is_dmt_match(nfs[icount].ty, &self.dmt_from_ref(&self.nfs[count + icount].ty)) { + if !self.is_dmt_match( + nfs[icount].ty, + &self.dmt_from_ref(&self.nfs[count + icount].ty), + ) { count += 1; continue 'outer; } @@ -848,157 +847,6 @@ impl<'a, const DMTS: usize, const RUNDMTS: usize, const NFS: usize, const VNTS: } None } - - ////// - - // const fn slurp_run_dmts_data(&mut self, data: &Data) { - // match data { - // Data::Unit => (), - // Data::Newtype(data_model_type) => self.slurp_run_dmts(data_model_type), - // Data::Tuple(data_model_types) => { - // let mut count = 0; - // while count < data_model_types.len() { - // self.slurp_run_dmts(data_model_types[count]); - // count += 1; - // } - // todo!() - // } - // Data::Struct(named_fields) => { - // let mut count = 0; - // while count < named_fields.len() { - // self.slurp_run_dmts(named_fields[count].ty); - // count += 1; - // } - // } - // } - // } - - // const fn slurp_non_run_dmts_data(&mut self, data: &Data) { - // match data { - // Data::Unit => {} - // Data::Newtype(data_model_type) => self.slurp_non_run_dmts(data_model_type), - // Data::Tuple(data_model_types) => { - // let mut count = 0; - // while count < data_model_types.len() { - // self.slurp_non_run_dmts(data_model_types[count]); - // count += 1; - // } - // } - // Data::Struct(named_fields) => { - // let mut count = 0; - // while count < named_fields.len() { - // self.slurp_non_run_dmts(named_fields[count].ty); - // count += 1; - // } - // if self.find_named_field_group(named_fields).is_some() { - // return; - // } - // let mut count = 0; - // while count < named_fields.len() {} - // } - // } - // } - - // const fn slurp_non_run_dmts(&mut self, dmt: &DataModelType) { - // match dmt { - // DataModelType::Bool => {} - // DataModelType::I8 => {} - // DataModelType::U8 => {} - // DataModelType::I16 => {} - // DataModelType::I32 => {} - // DataModelType::I64 => {} - // DataModelType::I128 => {} - // DataModelType::U16 => {} - // DataModelType::U32 => {} - // DataModelType::U64 => {} - // DataModelType::U128 => {} - // DataModelType::Usize => {} - // DataModelType::Isize => {} - // DataModelType::F32 => {} - // DataModelType::F64 => {} - // DataModelType::Char => {} - // DataModelType::String => {} - // DataModelType::ByteArray => {} - // DataModelType::Option(data_model_type) => self.slurp_non_run_dmts(data_model_type), - // DataModelType::Unit => {} - // DataModelType::Seq(data_model_type) => self.slurp_non_run_dmts(data_model_type), - // DataModelType::Tuple(data_model_types) => { - // let mut count = 0; - // while count < data_model_types.len() { - // self.slurp_non_run_dmts(data_model_types[count]); - // count += 1; - // } - // } - // DataModelType::Array { item, count } => self.slurp_non_run_dmts(item), - // DataModelType::Map { key, val } => { - // self.slurp_non_run_dmts(key); - // self.slurp_non_run_dmts(val); - // } - // DataModelType::Struct { name, data } => todo!(), - // DataModelType::Enum { name, variants } => todo!(), - // DataModelType::Schema => todo!(), - // } - // } - - // const fn slurp_run_dmts(&mut self, dmt: &DataModelType) { - // match dmt { - // DataModelType::Bool => {} - // DataModelType::I8 => {} - // DataModelType::U8 => {} - // DataModelType::I16 => {} - // DataModelType::I32 => {} - // DataModelType::I64 => {} - // DataModelType::I128 => {} - // DataModelType::U16 => {} - // DataModelType::U32 => {} - // DataModelType::U64 => {} - // DataModelType::U128 => {} - // DataModelType::Usize => {} - // DataModelType::Isize => {} - // DataModelType::F32 => {} - // DataModelType::F64 => {} - // DataModelType::Char => {} - // DataModelType::String => {} - // DataModelType::ByteArray => {} - // DataModelType::Option(data_model_type) => self.slurp_run_dmts(data_model_type), - // DataModelType::Unit => {} - // DataModelType::Seq(data_model_type) => self.slurp_run_dmts(data_model_type), - // DataModelType::Tuple(data_model_types) => { - // let mut count = 0; - // while count < data_model_types.len() { - // self.slurp_run_dmts(data_model_types[count]); - // count += 1; - // } - // if self.find_run_dmt(data_model_types).is_none() { - // // one pass over the types to push any subdeps to dmts, then - // // a second pass to fill in the run dmts? - // todo!() - // } - // } - // DataModelType::Array { item, count: _ } => self.slurp_run_dmts(item), - // DataModelType::Map { key, val } => { - // self.slurp_run_dmts(key); - // self.slurp_run_dmts(val); - // } - // DataModelType::Struct { name: _, data } => self.slurp_run_dmts_data(data), - // DataModelType::Enum { name: _, variants } => { - // let mut count = 0; - // while count < variants.len() { - // self.slurp_run_dmts_data(&variants[count].data); - // count += 1; - // } - // } - // DataModelType::Schema => todo!(), - // } - // } - - const fn push_run_dmt(self, dmts: &[&DataModelType]) -> Self { - if self.find_run_dmt(dmts).is_some() { - return self; - } - todo!() - // didn't find, extend - } } pub struct InternedSchema<'a, const DMTS: usize, const NFS: usize, const VNTS: usize> { @@ -1009,16 +857,9 @@ pub struct InternedSchema<'a, const DMTS: usize, const NFS: usize, const VNTS: u } pub mod ty_intern { - use crate::schema::intern::str_intern::streq; use crate::schema::Data; use crate::schema::DataModelType; - use super::InternData; - use super::InternDataModelGroupRef; - use super::InternDataModelType; - use super::InternNamedField; - use super::InternVariant; - ////////////////////////////////////////////////////////////////////// // RUN DMTS ////////////////////////////////////////////////////////////////////// @@ -1110,269 +951,6 @@ pub mod ty_intern { } } - // pub const fn is_data_match( - // data: &Data, - // intern: &InternData, - // idmts: &[InternDataModelType], - // infs: &[InternNamedField], - // ivars: &[InternVariant], - // istrs: &str, - // ) -> bool { - // match (data, intern) { - // (Data::Unit, InternData::Unit) => true, - // (Data::Newtype(data_model_type), InternData::Newtype(intern_data_model_type_ref)) => { - // is_dmt_match( - // data_model_type, - // intern_data_model_type_ref.idx, - // idmts, - // infs, - // ivars, - // istrs, - // ) - // } - // (Data::Tuple(data_model_types), InternData::Tuple(intern_data_model_group_ref)) => { - // if data_model_types.len() != intern_data_model_group_ref.len { - // return false; - // } - // let mut count = 0; - // while count < data_model_types.len() { - // let m = is_dmt_match( - // data_model_types[count], - // count + intern_data_model_group_ref.offset, - // idmts, - // infs, - // ivars, - // istrs, - // ); - // if !m { - // return false; - // } - // count += 1; - // } - // true - // } - // (Data::Struct(named_fields), InternData::Struct(intern_named_field_group_ref)) => { - // if named_fields.len() != intern_named_field_group_ref.len { - // return false; - // } - // let mut count = 0; - // while count < named_fields.len() { - // let offct = intern_named_field_group_ref.offset + count; - // let inf = &infs[offct]; - // if !streq( - // named_fields[count].name, - // str_subslice(istrs, inf.name.offset, inf.name.len), - // ) { - // return false; - // } - // if !is_dmt_match( - // named_fields[count].ty, - // inf.ty.idx, - // idmts, - // infs, - // ivars, - // istrs, - // ) { - // return false; - // } - // count += 1; - // } - // true - // } - // _ => false, - // } - // } - - // pub const fn is_dmt_match( - // dmt: &DataModelType, - // idx: usize, - // idmts: &[InternDataModelType], - // infs: &[InternNamedField], - // ivars: &[InternVariant], - // istrs: &str, - // ) -> bool { - // match (idmts[idx], dmt) { - // (InternDataModelType::Bool, DataModelType::Bool) => true, - // (InternDataModelType::I8, DataModelType::I8) => true, - // (InternDataModelType::U8, DataModelType::U8) => true, - // (InternDataModelType::I16, DataModelType::I16) => true, - // (InternDataModelType::I32, DataModelType::I32) => true, - // (InternDataModelType::I64, DataModelType::I64) => true, - // (InternDataModelType::I128, DataModelType::I128) => true, - // (InternDataModelType::U16, DataModelType::U16) => true, - // (InternDataModelType::U32, DataModelType::U32) => true, - // (InternDataModelType::U64, DataModelType::U64) => true, - // (InternDataModelType::U128, DataModelType::U128) => true, - // (InternDataModelType::Usize, DataModelType::Usize) => true, - // (InternDataModelType::Isize, DataModelType::Isize) => true, - // (InternDataModelType::F32, DataModelType::F32) => true, - // (InternDataModelType::F64, DataModelType::F64) => true, - // (InternDataModelType::Char, DataModelType::Char) => true, - // (InternDataModelType::String, DataModelType::String) => true, - // (InternDataModelType::ByteArray, DataModelType::ByteArray) => true, - // ( - // InternDataModelType::Option(intern_data_model_type_ref), - // DataModelType::Option(data_model_type), - // ) => is_dmt_match( - // data_model_type, - // intern_data_model_type_ref.idx, - // idmts, - // infs, - // ivars, - // istrs, - // ), - // (InternDataModelType::Unit, DataModelType::Unit) => true, - // ( - // InternDataModelType::Seq(intern_data_model_type_ref), - // DataModelType::Seq(data_model_type), - // ) => is_dmt_match( - // data_model_type, - // intern_data_model_type_ref.idx, - // idmts, - // infs, - // ivars, - // istrs, - // ), - // ( - // InternDataModelType::Tuple(intern_data_model_group_ref), - // DataModelType::Tuple(data_model_types), - // ) => { - // if intern_data_model_group_ref.len != data_model_types.len() { - // return false; - // } - // let mut count = 0; - // while count < data_model_types.len() { - // let idm = intern_data_model_group_ref.offset + count; - // if !is_dmt_match(data_model_types[count], idm, idmts, infs, ivars, istrs) { - // return false; - // } - // count += 1; - // } - // true - // } - // ( - // InternDataModelType::Array { item, count }, - // DataModelType::Array { - // item: ditem, - // count: dcount, - // }, - // ) => (count == *dcount) && is_dmt_match(ditem, item.idx, idmts, infs, ivars, istrs), - // ( - // InternDataModelType::Map { key, val }, - // DataModelType::Map { - // key: dkey, - // val: dval, - // }, - // ) => { - // is_dmt_match(dkey, key.idx, idmts, infs, ivars, istrs) - // && is_dmt_match(dval, val.idx, idmts, infs, ivars, istrs) - // } - // ( - // InternDataModelType::Struct { name, data }, - // DataModelType::Struct { - // name: dname, - // data: ddata, - // }, - // ) => { - // let name_match = streq(str_subslice(istrs, name.offset, name.len), dname); - // let data_match = is_data_match(ddata, &data, idmts, infs, ivars, istrs); - // name_match && data_match - // } - // ( - // InternDataModelType::Enum { name, variants }, - // DataModelType::Enum { - // name: dname, - // variants: dvariants, - // }, - // ) => { - // if !streq(str_subslice(istrs, name.offset, name.len), dname) { - // return false; - // } - // if variants.len != dvariants.len() { - // return false; - // } - // let mut count = 0; - // while count < dvariants.len() { - // let ivar = &ivars[variants.offset + count]; - // if !streq( - // dvariants[count].name, - // str_subslice(istrs, ivar.name.offset, ivar.name.len), - // ) { - // return false; - // } - // if !is_data_match( - // &dvariants[count].data, - // &ivar.data, - // idmts, - // infs, - // ivars, - // istrs, - // ) { - // return false; - // } - // count += 1; - // } - // true - // } - // (InternDataModelType::Schema, DataModelType::Schema) => todo!(), - // _ => false, - // } - // } - - // pub const fn find_run_dmt( - // dmts: &[&DataModelType], - // idmts: &[InternDataModelType], - // infs: &[InternNamedField], - // ivars: &[InternVariant], - // istrs: &str, - // ) -> Option { - // if idmts.len() < dmts.len() { - // return None; - // } - // assert!(!dmts.is_empty()); - - // let mut count = 0; - // 'outer: while count < (idmts.len() - dmts.len()) { - // let mut icount = 0; - // while icount < dmts.len() { - // if !is_dmt_match(dmts[icount], count + icount, idmts, infs, ivars, istrs) { - // count += 1; - // continue 'outer; - // } - // icount += 1; - // } - // return Some(InternDataModelGroupRef { - // offset: count, - // len: dmts.len(), - // }); - // } - // None - // } - - // pub const fn collect_all_run_dmts_data( - // data: &Data, - // ) -> ([InternDataModelType; N], usize) { - // let mut out = [const { InternDataModelType::Schema }; N]; - // let mut ct = 0; - // match data { - // Data::Unit => (out, ct), - // Data::Newtype(data_model_type) => collect_all_run_dmts(data_model_type), - // Data::Tuple(data_model_types) => { - // if let Some(_) = find_run_dmt(data_model_types, &out, infs, ivars, istrs) { - // todo!() - // } else { - // todo!() - // } - // } - // Data::Struct(named_fields) => todo!(), - // } - // } - // pub const fn collect_all_run_dmts( - // dmt: &DataModelType, - // ) -> ([InternDataModelType; N], usize) { - // todo!() - // } - ////////////////////////////////////////////////////////////////////// // Named Fields ////////////////////////////////////////////////////////////////////// diff --git a/source/postcard-schema-ng/tests/schema.rs b/source/postcard-schema-ng/tests/schema.rs index c819c0f4..b99bd3cd 100644 --- a/source/postcard-schema-ng/tests/schema.rs +++ b/source/postcard-schema-ng/tests/schema.rs @@ -183,10 +183,7 @@ struct TestStruct2<'a> { w: (u8, u16, u32), x: TestEnum<'a>, xa: TestEnum<'a>, - xb: TestEnum<'a>, y: TestStruct1, - ya: TestStruct1, - yb: TestStruct1, z: Result, }