frame_suite/
virtuals.rs

1// SPDX-License-Identifier: MPL-2.0
2//
3// Part of Auguth Labs open-source softwares.
4// Built for the Substrate framework.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at https://mozilla.org/MPL/2.0/.
9//
10// Copyright (c) 2026 Auguth Labs (OPC) Pvt Ltd, India
11
12// ===============================================================================
13// ```````````````````````````````` VIRTUALS SUITE ```````````````````````````````
14// ===============================================================================
15
16//! Virtual struct system mapping discriminants (ZSTs) to behavior via
17//! trait-driven schemas.
18//!
19//! Traditional Rust data structures require committing upfront to:
20//! - a fixed shape (`Option<T>`, `Vec<T>`, `[T; N]`, struct fields)
21//! - a fixed cardinality (single vs multiple)
22//! - a fixed storage layout
23//!
24//! This makes evolution difficult:
25//! - structure and storage are tightly coupled
26//! - generic abstractions often hit coherence limits
27//! - external composition (plugins, schemas) is hard
28//! - changing a field (`None -> Some -> Many`) requires redesign
29//!
30//! This module introduces a system where **structure, interpretation,
31//! and storage are decoupled**, and resolved through types.
32//!
33//! ## Mental Model: Virtual Structs
34//!
35//! Think in terms of a **virtual struct**, whose fields are not stored
36//! directly, but defined through traits and discriminants:
37//!
38//! ```ignore
39//! struct <T as Trait>::Struct<K> {
40//!     FieldTag: T::Field, // virtual field (identified by discriminant)
41//!     ExtTag: K,          // virtual extension (identified by discriminant)
42//! }
43//! ```
44//!
45//! This is not a concrete struct. Instead:
46//!
47//! - fields are accessed via trait implementations
48//! - each field is identified by a **discriminant (type-level key)**
49//! - storage is abstracted or external
50//!
51//! ## Discriminants (Field Identifiers)
52//!
53//! ```ignore
54//! struct FieldTag;
55//! struct ExtTag;
56//! ```
57//!
58//! Discriminants are zero-sized types used as **type-level field keys**.
59//!
60//! They act as:
61//! - field identifiers in the virtual struct
62//! - selectors for behavior and interpretation
63//! - disambiguators for generic implementations
64//!
65//! This ensures:
66//! - multiple fields can coexist without ambiguity
67//! - overlapping generic impls remain coherence-safe
68//!
69//! ## Trait as Schema
70//!
71//! ```ignore
72//! pub trait Trait {
73//!     type Struct: VirtualDynField<FieldTag, Some = Self::Field>
74//!                 + VirtualDynExtension<ExtTag>;
75//!
76//!     type Field;
77//! }
78//! ```
79//!
80//! - `Struct` is the container (virtual struct)
81//! - `FieldTag` identifies a logical field
82//! - `ExtTag` identifies an extension slot
83//! - `Field` defines the logical type of the field
84//!
85//! Traits define the **schema**, not the storage.
86//!
87//! ## Field Behavior (Cardinality Abstraction)
88//!
89//! A virtual field supports:
90//!
91//! - `None`  - no value
92//! - `Some`  - one value
93//! - `Many`  - multiple values
94//!
95//! This replaces fixed representations like:
96//!
97//! ```ignore
98//! Option<T> / Vec<T>
99//! ```
100//!
101//! with a single abstraction that can evolve without redesign.
102//!
103//! ## Key Insight
104//!
105//! A virtual struct is not a fixed layout, but a **composition of
106//! discriminant-keyed behaviors**, where:
107//!
108//! - **discriminants** -> field identifiers
109//! - **traits** -> schema (what exists)
110//! - **implementations** -> storage (how/where it exists)
111//!
112//! Structure is resolved by types, not encoded directly.
113//!
114//! ## Core Primitives
115//!
116//! The system is built from:
117//!
118//! ### Virtual Fields
119//! - [`VirtualDynField`] - dynamic, vector-like semantics
120//! - [`VirtualStaticField`] - static, array-like semantics
121//!
122//! ### Virtual Extensions
123//! - [`VirtualDynExtension`] / [`VirtualStaticExtension`]
124//! - externally defined fields via schemas
125//!
126//! ### Schemas & Bounds
127//! - [`VirtualDynBound`] / [`VirtualStaticBound`]
128//! - constraints defined independently of storage
129//!
130//! ### Concrete Representations
131//! - [`SumDynType`] - bounded vector semantics (`None | Some | Many`)
132//! - [`SumStaticType`] - fixed array semantics
133//!
134//! ## Design Principles
135//!
136//! ### Discriminant-Keyed Design
137//!
138//! All components are keyed by a [`DiscriminantTag`].
139//!
140//! This:
141//! - avoids ambiguity in generic implementations
142//! - enables multiple independent fields on the same container
143//! - ensures coherence-safe extensibility
144//!
145//! ### Tagged Conversions
146//!
147//! Instead of `From` / `Into`, the system uses:
148//!
149//! - [`FromTag`], [`IntoTag`]
150//! - [`TryFromTag`], [`TryIntoTag`]
151//!
152//! Conversions are disambiguated by discriminants:
153//! - [`NoneTag`] - absence
154//! - [`SomeTag`] - single value
155//! - [`ManyTag`] - multiple values
156//!
157//! This avoids overlapping implementations in generic contexts.
158//!
159//! ### Layered Model
160//!
161//! The system separates:
162//!
163//! - **Type-level layer**
164//!   - defines structure, schema, and behavior
165//!
166//! - **Value-level layer**
167//!   - represents `None`, `Some`, `Many`
168//!
169//! This enables abstract structure with concrete representations.
170//!
171//! ### Dynamic vs Static
172//!
173//! #### Dynamic (Runtime Flexible)
174//! - vector-like semantics
175//! - runtime bounds (`Get<u32>`)
176//! - growable/shrinkable collections
177//!
178//! #### Static (Compile-Time Fixed)
179//! - array-like semantics
180//! - compile-time bounds (`const`)
181//! - zero-overhead representations
182//!
183//! ## Helpers
184//!
185//! Ergonomic helpers are provided for working with virtual components:
186//!
187//! - [`DynFieldHelpers`] / [`StaticFieldHelpers`]
188//! - [`DynExtHelpers`] / [`StaticExtHelpers`]
189//!
190//! ## Summary
191//!
192//! This system enables:
193//!
194//! - evolving data shapes without redesign
195//! - discriminant-keyed field composition
196//! - external composition via schemas and extensions
197//! - reuse of storage across multiple logical fields
198//! - coherence-safe generic abstractions
199//!
200//! It provides a **type-level virtualization layer** where:
201//!
202//! > A virtual struct is a mapping from **discriminants -> behaviors**,
203//! > resolved through traits and implemented via storage.
204
205// ===============================================================================
206// ``````````````````````````````````` IMPORTS ```````````````````````````````````
207// ===============================================================================
208
209// --- Local crate imports ---
210use crate::base::{Buffer, Collection, Delimited, Growable, Indexable, RuntimeError};
211
212// --- Core (Rust std replacement) ---
213use core::fmt::{self, Debug};
214
215// --- Scale-codec crates ---
216use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, MaxEncodedLen};
217use scale_info::TypeInfo;
218
219// --- FRAME Support ---
220use frame_support::{
221    storage::types::{
222        EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, KeyGenerator,
223        ReversibleKeyGenerator, TupleToEncodedIter,
224    },
225    IterableStorageMap, IterableStorageNMap, StorageMap, StorageNMap, StoragePrefixedMap,
226};
227
228// --- Substrate primitives ---
229use sp_core::{ConstU32, Get};
230use sp_runtime::{traits::Zero, BoundedVec, Vec};
231use sp_std::vec;
232
233// ===============================================================================
234// ```````````````````````````````` DISCRIMINANTS ````````````````````````````````
235// ===============================================================================
236
237/// Marker trait for type-level discriminants.
238///
239/// A `Discriminant` is a zero-sized type used to uniquely identify behavior,
240/// structure, or interpretation at the type level.
241///
242/// ## Guidelines
243///
244/// Implementors should:
245/// - be zero-sized types (ZST)
246/// - carry no runtime data
247/// - act purely as type-level identifiers
248///
249/// ## Motivation
250///
251/// In Rust, trait implementations involving generic or associated types can
252/// become ambiguous under the coherence rules:
253///
254/// - generic parameters may unify in unexpected ways
255/// - multiple impls may overlap when types are not fully concrete
256/// - the compiler must conservatively reject such cases
257///
258/// To avoid this, a **concrete type-level key** is introduced as a discriminant.
259///
260/// By adding a `Discriminant`:
261/// - each implementation becomes uniquely identifiable
262/// - ambiguity between generic impls is disposed
263/// - coherence is preserved without restricting expressiveness
264///
265/// ## Role in the System
266///
267/// Discriminants are used in some cases like
268/// - keys for [`VirtualDynField`]
269/// - identifiers for [`plugin`](crate::plugins) operations
270/// - selectors for tagged conversions ([`FromTag`], [`IntoTag`], etc.)
271///
272/// They allow multiple interpretations over the same underlying types
273/// without conflict.
274pub trait DiscriminantTag {}
275
276/// Default Discriminant implementation if no
277/// multiple interpretations are required.
278impl DiscriminantTag for () {}
279
280/// Defines one or more public zero-sized discriminant types.
281///
282/// A *discriminant* is a concrete type-level key used to uniquely identify
283/// behavior, structure, or interpretation in generic systems.
284///
285/// ## Why Discriminants?
286///
287/// In Rust, trait implementations over generic or associated types can become
288/// ambiguous under coherence rules:
289/// - generic types may unify in multiple ways
290/// - implementations may overlap when types are not fully concrete
291/// - the compiler must reject such cases conservatively
292///
293/// Discriminants solve this by introducing a **concrete, unique type**
294/// that disambiguates otherwise overlapping implementations.
295///
296/// This enables:
297/// - multiple interpretations over the same types
298/// - safe composition of generic abstractions
299/// - coherence-safe extensibility
300///
301/// ## Syntax
302///
303/// ```ignore
304/// discriminants!(
305///     /// Optional docs or attributes
306///     A,
307///
308///     B,
309///
310///     #[cfg(feature = "x")]
311///     C,
312/// );
313/// ```
314///
315/// ## Expansion
316///
317/// For each identifier, this macro generates:
318/// - a `pub` zero-sized struct
319/// - an implementation of [`DiscriminantTag`]
320///
321/// ## Properties
322///
323/// - zero runtime cost (ZSTs)
324/// - purely type-level identifiers
325/// - stable and unambiguous across generic contexts
326/// - reusable across virtual fields, extensions, and
327/// [`plugin`](crate::plugins) systems
328///
329/// ## Why Always Public
330///
331/// Discriminants appear in type signatures and generic bounds,
332/// making them part of the public type-level API.
333///
334/// Restricting visibility would:
335/// - prevent use in external generic constraints
336/// - break composability across modules or crates
337/// - force duplication of identical identifiers
338///
339/// In practice, discriminants are **type-level contracts**, not internal details.
340#[macro_export]
341macro_rules! discriminants {
342    (
343        $(
344            $(#[$meta:meta])*
345            $name:ident
346        ),* $(,)?
347    ) => {
348        $(
349            $(#[$meta])*
350            #[derive(Clone, Copy, Debug, Default)]
351            pub struct $name;
352
353            impl $crate::virtuals::DiscriminantTag for $name {}
354        )*
355    };
356}
357
358/// Implements [`DiscriminantTag`] for one or more existing types.
359///
360/// This macro allows pre-existing types to act as discriminants without
361/// redefining them.
362///
363/// ## Why Discriminants?
364///
365/// Discriminants provide a **concrete type-level key** that avoids ambiguity
366/// in generic trait resolution under Rust's coherence rules.
367///
368/// By associating behavior with a discriminant instead of relying solely
369/// on generic types, implementations become:
370/// - uniquely identifiable
371/// - non-overlapping
372/// - composable across abstraction boundaries
373///
374/// ## When to Use
375///
376/// Use this macro when:
377/// - a type already exists and should act as a discriminant
378/// - redefining it as a new ZST would be redundant or impossible
379///
380/// ## Syntax
381///
382/// ```ignore
383/// struct MyTag;
384/// struct OtherTag;
385///
386/// impl_discriminants!(MyTag, OtherTag);
387/// ```
388///
389/// ## Behavior
390///
391/// - Implements [`DiscriminantTag`] for each provided type
392/// - Preserves the original type definition
393///
394/// ## Notes
395///
396/// - Types are expected to behave like discriminants (typically ZSTs)
397/// - No runtime guarantees are enforced; this is a semantic contract
398///
399/// ## Summary
400///
401/// This macro extends the discriminant system to existing types,
402/// enabling reuse and integration without redefining identifiers.
403#[macro_export]
404macro_rules! impl_discriminants {
405    (
406        $(
407            $(#[$meta:meta])*
408            $ty:ty
409        ),* $(,)?
410    ) => {
411        $(
412            $(#[$meta])*
413            impl $crate::virtuals::DiscriminantTag for $ty {}
414        )*
415    };
416}
417
418// ===============================================================================
419// ````````````````````` FROM/INTO DISCRIMINANTED CONVERSIONS ````````````````````
420// ===============================================================================
421
422/// Converts a value `T` into `Self` under a given discriminant.
423///
424/// Unlike [`From`], this trait introduces an additional type parameter
425/// (`Discriminant` implementing [`DiscriminantTag`] via
426/// [`discriminants`] or [`impl_discriminants`])
427/// to distinguish between conversions that would otherwise overlap under
428/// Rust's coherence rules.
429///
430/// This is necessary because:
431/// - `T` and `Self` may be generic or associated types (i.e., not fully concrete)
432/// - such types may unify in the future
433/// - the compiler must conservatively reject potentially overlapping impls
434///
435/// By adding a concrete discriminant (tag), each conversion becomes uniquely
436/// identifiable at the type level.
437///
438/// ## Type Parameters
439/// - `T`: Source type (may be generic or non-concrete).
440/// - `Discriminant`: A concrete marker type used to disambiguate conversions.
441///
442/// ## Default Discriminant
443///
444/// - `Discriminant = ()`: uses the unit type as a default tag,
445///   meaning no additional disambiguation when a single interpretation exists.
446pub trait FromTag<T, Discriminant: DiscriminantTag = ()>: Sized {
447    fn from_tag(t: T) -> Self;
448}
449
450/// Fallible version of [`FromTag`].
451///
452/// Allows conversions that may fail, while still being disambiguated by a
453/// concrete discriminant.
454///
455/// ## Type Parameters
456/// - `T`: Source type (may be generic or non-concrete).
457/// - `Discriminant`: A concrete marker type used to disambiguate conversions.
458///
459/// ## Default Discriminant
460///
461/// - `Discriminant = ()`: uses the unit type as a default tag,
462///   meaning no additional disambiguation when a single interpretation exists.
463pub trait TryFromTag<T, Discriminant: DiscriminantTag = ()>: Sized {
464    type Error;
465
466    fn try_from_tag(t: T) -> Result<Self, Self::Error>;
467}
468
469/// Converts `self` into another representation under a given discriminant.
470///
471/// This is the method-based counterpart to [`FromTag`]. It exists for ergonomic
472/// use, similar to how [`Into`] complements [`From`].
473///
474/// The additional discriminant ensures that conversions remain unambiguous even
475/// when source and target types are not fully concrete.
476///
477/// ## Type Parameters
478/// - `R`: Target type (may be generic or non-concrete).
479/// - `Discriminant`: A concrete marker type used to disambiguate conversions.
480///
481/// ## Default Discriminant
482///
483/// - `Discriminant = ()`: uses the unit type as a default tag,
484///   meaning no additional disambiguation when a single interpretation exists.
485pub trait IntoTag<R, Discriminant: DiscriminantTag = ()> {
486    fn into_tag(self) -> R;
487}
488
489/// Fallible version of [`IntoTag`].
490///
491/// Attempts to convert `self` into another representation under a given
492/// discriminant, returning an error if the conversion fails.
493///
494/// ## Type Parameters
495/// - `R`: Target type (may be generic or non-concrete).
496/// - `Discriminant`: A concrete marker type used to disambiguate conversions.
497///
498/// ## Default Discriminant
499///
500/// - `Discriminant = ()`: uses the unit type as a default tag,
501///   meaning no additional disambiguation when a single interpretation exists.
502pub trait TryIntoTag<R, Discriminant: DiscriminantTag = ()> {
503    type Error;
504
505    fn try_into_tag(self) -> Result<R, Self::Error>;
506}
507
508/// Blanket implementation of [`IntoTag`] for any type that implements [`FromTag`].
509///
510/// This mirrors the relationship between [`Into`] and [`From`], while preserving
511/// disambiguation via the discriminant.
512///
513/// The discriminant ensures that even when `T` and `U` are not fully concrete,
514/// the conversion remains uniquely identifiable and does not violate coherence.
515impl<T, U, Tag> IntoTag<U, Tag> for T
516where
517    U: FromTag<T, Tag>,
518    Tag: DiscriminantTag,
519{
520    fn into_tag(self) -> U {
521        U::from_tag(self)
522    }
523}
524
525// ===============================================================================
526// `````````````````````````````````` SUM TYPES ``````````````````````````````````
527// ===============================================================================
528
529discriminants! {
530    /// A discriminant representing the absence of a value in tagged conversions.
531    ///
532    /// This is a zero-sized type used as a type-level primitive to select
533    /// conversion behavior. It acts as a compile-time discriminator,
534    /// allowing multiple interpretations over the same types.
535    NoneTag,
536
537    /// A discriminant representing a single value in tagged conversions.
538    ///
539    /// This is a zero-sized type used as a type-level primitive to select
540    /// conversion behavior. It distinguishes conversions operating on
541    /// a singular value.
542    SomeTag,
543
544    /// A discriminant representing multiple values in tagged conversions.
545    ///
546    /// This is a zero-sized type used as a type-level primitive to select
547    /// conversion behavior. It distinguishes conversions operating on
548    /// collections of values.
549    ManyTag,
550}
551
552/// A concrete representation of field cardinality: zero, one, or many values.
553///
554/// `SumDynType` unifies the possible shapes of a field into a single type:
555/// - absence (`None`)
556/// - a single value (`Some`)
557/// - multiple values (`Many`)
558///
559/// ## Context
560///
561/// In the virtual field system:
562/// - [`VirtualDynField`] defines field behavior abstractly (type-level)
563/// - `SumDynType` provides a concrete, value-level representation
564///
565/// It is commonly used as the backing representation (`Repr`) for
566/// dynamically shaped fields.
567///
568/// ## Representation Model
569///
570/// The `Many` variant is backed by a [`BoundedVec`], giving it
571/// **vector-like semantics**:
572/// - dynamically sized (up to a bound)
573/// - growable and shrinkable
574/// - capacity enforced via a type-level limit
575///
576/// This makes `SumDynType` suitable for:
577/// - flexible schemas
578/// - deferred structure
579/// - abstraction across boundaries where size is not fixed
580///
581/// ## Variants
582/// - `None`: no value
583/// - `Some(Type)`: exactly one value
584/// - `Many(BoundedVec<Type, S>)`: multiple values with vector semantics
585///
586/// ## Type Parameters
587/// - `Type`: element type
588/// - `S`: type-level capacity bound
589///
590/// ## Key Property
591///
592/// This is a **concrete (non-virtual) representation** using
593/// **bounded vector semantics**, allowing flexible cardinality
594/// within a constrained capacity.
595///
596/// ## Default Generics
597///
598/// - `Type = ()`: no meaningful value (unit type)
599/// - `S = ConstU32<0>`: zero capacity, `Many` cannot store elements
600///
601/// Together, this yields a **no-op, zero-capacity representation**,
602/// useful as a placeholder in generic contexts.
603#[derive(Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo, Clone, Default, Debug)]
604#[scale_info(skip_type_params(S))]
605pub enum SumDynType<Type = (), S = ConstU32<0>>
606where
607    Type: Delimited,
608    S: Get<u32> + Clone + Debug + 'static,
609{
610    #[default]
611    None,
612    Some(Type),
613    Many(BoundedVec<Type, S>),
614}
615
616impl<Type, S> PartialEq for SumDynType<Type, S>
617where
618    Type: Delimited,
619    S: Get<u32> + Clone + fmt::Debug,
620{
621    fn eq(&self, other: &Self) -> bool {
622        match (self, other) {
623            (Self::None, Self::None) => true,
624            (Self::Some(a), Self::Some(b)) => a == b,
625            (Self::Many(a), Self::Many(b)) => a == b,
626            _ => false,
627        }
628    }
629}
630
631impl<Type, S> Eq for SumDynType<Type, S>
632where
633    Type: Delimited,
634    S: Get<u32> + Clone + fmt::Debug,
635{
636}
637
638impl<Type, S> FromTag<(), NoneTag> for SumDynType<Type, S>
639where
640    Type: Delimited,
641    S: Get<u32> + Clone + Debug + 'static,
642{
643    fn from_tag(_t: ()) -> Self {
644        SumDynType::None
645    }
646}
647
648impl<Type, S> TryIntoTag<(), NoneTag> for SumDynType<Type, S>
649where
650    Type: Delimited,
651    S: Get<u32> + Clone + Debug + 'static,
652{
653    type Error = ();
654
655    fn try_into_tag(self) -> Result<(), Self::Error> {
656        match self {
657            SumDynType::None => Ok(()),
658            _ => Err(()),
659        }
660    }
661}
662
663impl<Type, S> FromTag<Type, SomeTag> for SumDynType<Type, S>
664where
665    Type: Delimited,
666    S: Get<u32> + Clone + Debug + 'static,
667{
668    fn from_tag(t: Type) -> Self {
669        SumDynType::Some(t)
670    }
671}
672
673impl<Type, S> TryIntoTag<Type, SomeTag> for SumDynType<Type, S>
674where
675    Type: Delimited,
676    S: Get<u32> + Clone + Debug + 'static,
677{
678    type Error = ();
679
680    fn try_into_tag(self) -> Result<Type, Self::Error> {
681        match self {
682            SumDynType::Some(v) => Ok(v),
683            _ => Err(()),
684        }
685    }
686}
687
688impl<Type, S> TryFromTag<Vec<Type>, ManyTag> for SumDynType<Type, S>
689where
690    Type: Delimited,
691    S: Get<u32> + Clone + Debug + 'static,
692{
693    type Error = ();
694
695    fn try_from_tag(t: Vec<Type>) -> Result<Self, Self::Error> {
696        Ok(SumDynType::Many(
697            BoundedVec::<Type, S>::try_from(t).map_err(|_| ())?,
698        ))
699    }
700}
701
702impl<Type, S> IntoTag<Vec<Type>, ManyTag> for SumDynType<Type, S>
703where
704    Type: Delimited,
705    S: Get<u32> + Clone + Debug + 'static,
706{
707    fn into_tag(self) -> Vec<Type> {
708        match self {
709            SumDynType::None => Vec::new(),
710            SumDynType::Some(v) => vec![v],
711            SumDynType::Many(vec) => vec.to_vec(),
712        }
713    }
714}
715
716/// A statically shaped representation of field cardinality.
717///
718/// `SumStaticType` encodes the possible shapes of a field:
719/// - absence (`None`)
720/// - a single value (`Some`)
721/// - multiple values (`Many`)
722///
723/// ## Context
724///
725/// In the virtual field system:
726/// - [`VirtualStaticField`] defines fields whose structure is
727///   fully determined at compile time
728/// - `SumStaticType` provides a matching concrete representation
729///
730/// ## Representation Model
731///
732/// The `Many` variant is backed by a fixed-size array (`[Type; N]`),
733/// giving it **array-like semantics**:
734/// - size is fixed at compile time
735/// - no resizing or allocation
736/// - capacity is encoded directly in the type
737///
738/// This makes `SumStaticType` suitable for:
739/// - compile-time enforced layouts
740/// - fixed schemas
741/// - zero-overhead representations
742///
743/// ## Variants
744/// - `None`: no value
745/// - `Some(Type)`: exactly one value
746/// - `Many([Type; N])`: fixed-size collection with array semantics
747///
748/// ## Type Parameters
749/// - `Type`: element type
750/// - `N`: compile-time capacity
751///
752/// ## Key Property
753///
754/// This is a **fully determined representation** using
755/// **array semantics**, where both cardinality and capacity
756/// are encoded directly in the type.
757///
758/// ## Default Generics
759///
760/// - `Type = ()`: no meaningful value (unit type)
761/// - `N = 0`: zero-sized array, `Many` holds no elements
762///
763/// Together, this yields a **no-op, zero-sized representation**,
764/// useful as a placeholder in generic contexts.
765#[derive(
766    Encode,
767    Decode,
768    DecodeWithMemTracking,
769    MaxEncodedLen,
770    TypeInfo,
771    Clone,
772    Default,
773    Debug,
774    PartialEq,
775    Eq,
776)]
777pub enum SumStaticType<Type = (), const N: usize = 0>
778where
779    Type: Delimited,
780{
781    #[default]
782    None,
783    Some(Type),
784    Many([Type; N]),
785}
786
787impl<Type, const N: usize> FromTag<(), NoneTag> for SumStaticType<Type, N>
788where
789    Type: Delimited,
790{
791    fn from_tag(_t: ()) -> Self {
792        SumStaticType::None
793    }
794}
795
796impl<Type, const N: usize> TryIntoTag<(), NoneTag> for SumStaticType<Type, N>
797where
798    Type: Delimited,
799{
800    type Error = ();
801
802    fn try_into_tag(self) -> Result<(), Self::Error> {
803        match self {
804            SumStaticType::None => Ok(()),
805            _ => Err(()),
806        }
807    }
808}
809
810impl<Type, const N: usize> FromTag<Type, SomeTag> for SumStaticType<Type, N>
811where
812    Type: Delimited,
813{
814    fn from_tag(t: Type) -> Self {
815        SumStaticType::Some(t)
816    }
817}
818
819impl<Type, const N: usize> TryIntoTag<Type, SomeTag> for SumStaticType<Type, N>
820where
821    Type: Delimited,
822{
823    type Error = ();
824
825    fn try_into_tag(self) -> Result<Type, Self::Error> {
826        match self {
827            SumStaticType::Some(v) => Ok(v),
828            _ => Err(()),
829        }
830    }
831}
832
833impl<Type, const N: usize> FromTag<[Type; N], ManyTag> for SumStaticType<Type, N>
834where
835    Type: Delimited,
836{
837    fn from_tag(t: [Type; N]) -> Self {
838        SumStaticType::Many(t)
839    }
840}
841
842impl<Type, const N: usize> TryIntoTag<[Type; N], ManyTag> for SumStaticType<Type, N>
843where
844    Type: Delimited,
845{
846    type Error = ();
847
848    fn try_into_tag(self) -> Result<[Type; N], Self::Error> {
849        match self {
850            SumStaticType::Many(v) => Ok(v),
851            _ => Err(()),
852        }
853    }
854}
855
856// ===============================================================================
857// ```````````````````````````````` VIRTUAL FIELDS ```````````````````````````````
858// ===============================================================================
859
860/// A discriminant-keyed virtual field abstraction with flexible cardinality
861/// (`None`, `Some`, or `Many`).
862///
863/// This trait models a field whose structure is **deferred** and resolved
864/// through types rather than fixed upfront.
865///
866/// ## Model
867///
868/// A `VirtualDynField` behaves like a field in a logical record, without
869/// committing to:
870///
871/// - a concrete container (`Option`, `Vec`, etc.)
872/// - a fixed cardinality
873/// - or a fixed storage layout
874///
875/// Instead:
876/// - the **implementor** defines the backing representation (`Repr`)
877/// - the **caller** selects the shape (`None`, `Some`, or `Many`)
878///
879/// ## Representation Semantics
880///
881/// The `Many` form is expected to have **vector-like semantics**:
882/// - dynamically sized (within bounds)
883/// - growable and shrinkable
884/// - capacity enforced but not encoded in the type shape
885///
886/// This makes `VirtualDynField` suitable for:
887/// - flexible schemas
888/// - deferred structure
889/// - abstraction across boundaries
890///
891/// ## Discriminant
892///
893/// The `Discriminant` acts as a type-level key, allowing multiple independent
894/// fields to coexist without ambiguity.
895///
896/// ## Design
897///
898/// Responsibilities are separated:
899///
900/// - **Implementor (Storage Layer)**
901///   - defines representation (`Repr`)
902/// - **Caller (Shape Layer)**
903///   - selects cardinality and interpretation
904///
905/// This decouples logical meaning from physical storage.
906///
907/// ## When to Use
908///
909/// Use this trait when:
910/// - structure must remain flexible
911/// - cardinality is not known upfront
912/// - storage must be abstract and composable
913///
914/// ## Default Discriminant
915///
916/// - `Discriminant = ()`: uses the unit type as a single field key,
917///   meaning only one virtual field exists (no disambiguation needed).
918pub trait VirtualDynField<Discriminant: DiscriminantTag = ()>: Default {
919    /// Representation of absence.
920    type None: Delimited;
921
922    /// The logical element type stored in the virtual field.
923    type Some: Delimited;
924
925    /// A collection of `Some`.
926    ///
927    /// Must support buffering and indexed access.
928    type Many: Buffer<Self::Some>;
929
930    /// Opaque storage backing the virtual field.
931    ///
932    /// Encodes the actual data and must support tagged conversions
933    /// to and from `None`, `Some`, and `Many`.
934    type Repr: Delimited
935        // Provides an initial empty representation,
936        // allowing deferred population via mutation.
937        + Default
938        // Construct representation from absence
939        + FromTag<Self::None, NoneTag>
940        // Extract absence from representation
941        + TryIntoTag<Self::None, NoneTag>
942        // Construct representation from a single value
943        + FromTag<Self::Some, SomeTag>
944        // Extract a single value from representation
945        + TryIntoTag<Self::Some, SomeTag>
946        // Attempt to construct representation from many values
947        + TryFromTag<Self::Many, ManyTag>
948        // Convert representation into many values
949        + IntoTag<Self::Many, ManyTag>;
950
951    /// Returns the current representation of the virtual field.
952    ///
953    /// Interaction is performed via tagged conversions.
954    fn access(&self) -> Self::Repr;
955
956    /// Replaces the current representation.
957    ///
958    /// The provided value must satisfy representation invariants.
959    fn mutate(&mut self, v: Self::Repr);
960
961    /// Returns the current number of elements represented.
962    ///
963    /// Interpreted as:
964    /// - `None` -> 0
965    /// - `Some` -> 1
966    /// - `Many` -> n
967    fn len(&self) -> usize;
968
969    /// Returns the minimum number of elements representable.
970    fn min(&self) -> usize;
971
972    /// Returns the maximum number of elements representable.
973    fn max(&self) -> usize;
974}
975
976/// Trivial `None` conversion for unit.
977impl FromTag<(), NoneTag> for () {
978    fn from_tag(_t: ()) -> Self {}
979}
980
981/// Trivial `Some` conversion for unit.
982impl FromTag<(), SomeTag> for () {
983    fn from_tag(_t: ()) -> Self {}
984}
985
986/// Trivial `Many` conversion for unit (always succeeds).
987impl TryFromTag<Vec<()>, ManyTag> for () {
988    type Error = core::convert::Infallible;
989
990    fn try_from_tag(_t: Vec<()>) -> Result<Self, Self::Error> {
991        Ok(())
992    }
993}
994
995/// Trivial extraction of `None` from unit.
996impl TryIntoTag<(), NoneTag> for () {
997    type Error = core::convert::Infallible;
998
999    fn try_into_tag(self) -> Result<Self, Self::Error> {
1000        Ok(())
1001    }
1002}
1003
1004/// Trivial extraction of `Some` from unit.
1005impl TryIntoTag<(), SomeTag> for () {
1006    type Error = core::convert::Infallible;
1007
1008    fn try_into_tag(self) -> Result<Self, Self::Error> {
1009        Ok(())
1010    }
1011}
1012
1013/// Converts unit into an empty `Many` representation.
1014impl IntoTag<Vec<()>, ManyTag> for () {
1015    fn into_tag(self) -> Vec<()> {
1016        Vec::<()>::new()
1017    }
1018}
1019
1020/// No-op `VirtualDynField` implementation for unit.
1021///
1022/// Represents an allocation with no storage and zero capacity.
1023impl VirtualDynField for () {
1024    type None = ();
1025    type Some = ();
1026    type Many = Vec<()>;
1027    type Repr = ();
1028
1029    fn access(&self) -> Self::Repr {
1030        ()
1031    }
1032
1033    fn mutate(&mut self, _: Self::Repr) {}
1034
1035    fn len(&self) -> usize {
1036        Zero::zero()
1037    }
1038
1039    fn min(&self) -> usize {
1040        Zero::zero()
1041    }
1042
1043    fn max(&self) -> usize {
1044        Zero::zero()
1045    }
1046}
1047
1048// ===============================================================================
1049// ```````````````````````` VIRTUAL FIELD DEFAULT-HELPERS ````````````````````````
1050// ===============================================================================
1051
1052/// A discriminant-keyed virtual field abstraction with statically
1053/// determined cardinality.
1054///
1055/// This trait models a field whose structure is **fully determined
1056/// at compile time**, rather than deferred.
1057///
1058/// ## Model
1059///
1060/// A `VirtualStaticField` behaves like a field in a logical record,
1061/// where:
1062///
1063/// - cardinality is fixed or constrained at compile time
1064/// - storage shape is predetermined
1065/// - no dynamic resizing or growth is expected
1066///
1067/// Similar to [`VirtualDynField`] (but not dynamically sized):
1068/// - the **implementor** defines the backing representation (`Repr`)
1069/// - the **caller** selects the interpretation (`None`, `Some`, `Many`)
1070///
1071/// ## Representation Semantics
1072///
1073/// The `Many` form is expected to have **array-like semantics**:
1074/// - fixed size
1075/// - no resizing or allocation
1076/// - capacity encoded directly in the type
1077///
1078/// This makes `VirtualStaticField` suitable for:
1079/// - compile-time enforced layouts
1080/// - fixed schemas
1081/// - zero-overhead representations
1082///
1083/// ## Discriminant
1084///
1085/// The `Discriminant` acts as a type-level key, allowing multiple independent
1086/// fields to coexist without ambiguity.
1087///
1088/// ## Design
1089///
1090/// As with dynamic fields, responsibilities are separated:
1091///
1092/// - **Implementor (Storage Layer)**
1093///   - defines representation (`Repr`)
1094/// - **Caller (Shape Layer)**
1095///   - selects cardinality and interpretation
1096///
1097/// The key difference is that structure is **not deferred**, but
1098/// fully determined at compile time.
1099///
1100/// ## When to Use
1101///
1102/// Use this trait when:
1103/// - structure is known and fixed upfront
1104/// - dynamic resizing is unnecessary or undesirable
1105/// - compile-time guarantees are preferred over flexibility
1106///
1107/// ## Default Discriminant
1108///
1109/// - `Discriminant = ()`: uses the unit type as a single field key,
1110///   meaning only one virtual field exists (no disambiguation needed).
1111pub trait VirtualStaticField<Discriminant: DiscriminantTag = ()>: Default {
1112    /// Representation of absence.
1113    type None: Delimited;
1114
1115    /// The logical element type stored in the virtual field.
1116    type Some: Delimited;
1117
1118    /// A collection of `Some`.
1119    ///
1120    /// Must support indexed access and have a statically
1121    /// determined size (array-like semantics).
1122    type Many: Collection<Self::Some>;
1123
1124    /// Opaque storage backing the virtual field.
1125    ///
1126    /// Encodes the field state and supports tagged conversions
1127    /// between `None`, `Some`, and `Many`.
1128    ///
1129    /// Unlike dynamic fields, this representation is expected to
1130    /// be fully determined at compile time and not rely on
1131    /// dynamic resizing or buffering.
1132    type Repr: Delimited
1133        // Provides an initial representation.
1134        + Default
1135        // Construct representation from absence
1136        + FromTag<Self::None, NoneTag>
1137        // Extract absence from representation
1138        + TryIntoTag<Self::None, NoneTag>
1139        // Construct representation from a single value
1140        + FromTag<Self::Some, SomeTag>
1141        // Extract a single value from representation
1142        + TryIntoTag<Self::Some, SomeTag>
1143        // Construct representation from many values
1144        + FromTag<Self::Many, ManyTag>
1145        // Extract many values from representation
1146        + TryIntoTag<Self::Many, ManyTag>;
1147
1148    /// Returns the current representation of the virtual field.
1149    ///
1150    /// Interaction is performed via tagged conversions.
1151    fn access(&self) -> Self::Repr;
1152
1153    /// Replaces the current representation.
1154    ///
1155    /// The provided value must satisfy representation invariants.
1156    fn mutate(&mut self, v: Self::Repr);
1157}
1158
1159/// Trivial `Many` conversion for unit using a zero-sized array.
1160impl FromTag<[(); 0], ManyTag> for () {
1161    fn from_tag(_t: [(); 0]) -> Self {}
1162}
1163
1164/// Trivial extraction of `Many` as a zero-sized array from unit.
1165impl TryIntoTag<[(); 0], ManyTag> for () {
1166    type Error = core::convert::Infallible;
1167
1168    fn try_into_tag(self) -> Result<[(); 0], Self::Error> {
1169        Ok([(); 0])
1170    }
1171}
1172
1173/// No-op `VirtualStaticField` implementation for unit.
1174///
1175/// Represents an allocation with no storage and zero capacity.
1176impl VirtualStaticField for () {
1177    type None = ();
1178    type Some = ();
1179    type Many = [(); 0];
1180    type Repr = ();
1181
1182    fn access(&self) -> Self::Repr {
1183        ()
1184    }
1185
1186    fn mutate(&mut self, _: Self::Repr) {}
1187}
1188
1189/// Helper methods for accessing and mutating values in a [`VirtualDynField`].
1190///
1191/// These helpers operate on **dynamically shaped fields** with
1192/// **vector-like semantics**:
1193/// - collections may grow or shrink (within bounds)
1194/// - indexing and iteration are supported
1195/// - mutations may reallocate or fail due to bounds
1196///
1197/// All operations are performed via tagged conversions.
1198///
1199/// ## Default Discriminant
1200///
1201/// - `K = ()`: operates on a single default field,
1202///   meaning one virtual field is assumed.
1203pub trait DynFieldHelpers<K = ()>: VirtualDynField<K>
1204where
1205    K: DiscriminantTag,
1206{
1207    /// Returns the element at `index` from the field interpreted as `Many`.
1208    ///
1209    /// ## Behavior
1210    /// - Returns `Some(V)` if the field contains a collection and `index` is in bounds
1211    /// - Returns `None` if the field is `None`, `Some`, or out of bounds
1212    fn index_get(&self, index: usize) -> Option<Self::Some>
1213    where
1214        Self::Some: Clone,
1215    {
1216        <Self as VirtualDynField<K>>::access(self)
1217            .into_tag()
1218            .as_ref()
1219            .get(index)
1220            .cloned()
1221    }
1222
1223    /// Returns an iterator over elements in the field interpreted as `Many`.
1224    ///
1225    /// If the field is not `Many`, the iterator will be empty.
1226    fn iter(&self) -> impl Iterator<Item = Self::Some>
1227    where
1228        Self::Some: Clone,
1229    {
1230        <Self as VirtualDynField<K>>::access(self)
1231            .into_tag()
1232            .into_iter()
1233    }
1234
1235    /// Applies a mutable operation to each element in the field interpreted as `Many`.
1236    ///
1237    /// After mutation, the updated collection is written back to the container.
1238    ///
1239    /// ## Errors
1240    /// - Returns `Err(())` if conversion back into the representation fails
1241    fn iter_mut<F>(&mut self, mut f: F) -> Result<(), ()>
1242    where
1243        F: FnMut(&mut Self::Some),
1244    {
1245        let mut vec = <Self as VirtualDynField<K>>::access(self).into_tag();
1246
1247        let len = vec.as_ref().len();
1248        for i in 0..len {
1249            f(&mut vec[i]);
1250        }
1251
1252        let repr = TryFromTag::try_from_tag(vec).map_err(|_| ())?;
1253        <Self as VirtualDynField<K>>::mutate(self, repr);
1254
1255        Ok(())
1256    }
1257
1258    /// Sets the element at `index` in the field interpreted as `Many`.
1259    ///
1260    /// If the field is not currently a collection or is too short,
1261    /// it is extended with default values.
1262    ///
1263    /// ## Errors
1264    /// - Returns `Err(())` if conversion back fails
1265    fn index_set(&mut self, index: usize, value: Self::Some) -> Result<(), ()>
1266    where
1267        Self::Some: Default,
1268    {
1269        let mut v = <Self as VirtualDynField<K>>::access(self).into_tag();
1270
1271        set_index(&mut v, index, value);
1272
1273        let repr = TryFromTag::try_from_tag(v).map_err(|_| ())?;
1274        <Self as VirtualDynField<K>>::mutate(self, repr);
1275
1276        Ok(())
1277    }
1278
1279    /// Retrieves the value of the field interpreted as `Some`.
1280    ///
1281    /// ## Behavior
1282    /// - Returns `Some(V)` if the field contains a single value
1283    /// - Returns `None` otherwise
1284    fn get(&self) -> Option<Self::Some> {
1285        let repr = <Self as VirtualDynField<K>>::access(self);
1286        TryIntoTag::<_, SomeTag>::try_into_tag(repr).ok()
1287    }
1288
1289    /// Sets the field to a single value (`Some`).
1290    ///
1291    /// Replaces any existing representation.
1292    fn set(&mut self, v: Self::Some)
1293    where
1294        Self::Some: Delimited,
1295    {
1296        <Self as VirtualDynField<K>>::mutate(self, v.into_tag());
1297    }
1298}
1299
1300/// Blanket impl for all [`VirtualDynField`] types.
1301///
1302/// This trait is not intended to be implemented manually.
1303/// It exists as an ergonomic replacement for free helper functions.
1304///
1305/// All methods have default implementations, making this
1306/// forward-compatible: new helpers can be added without
1307/// breaking existing code.
1308impl<T, K> DynFieldHelpers<K> for T
1309where
1310    T: VirtualDynField<K>,
1311    K: DiscriminantTag,
1312{
1313}
1314
1315/// Helper methods for accessing and mutating values in a [`VirtualStaticField`].
1316///
1317/// These helpers operate on **statically shaped fields** with
1318/// **array-like semantics**:
1319/// - collection size is fixed at compile time
1320/// - no resizing or extension is performed
1321/// - operations replace or read the entire structure
1322///
1323/// All operations are performed via tagged conversions.
1324///
1325/// ## Default Discriminant
1326///
1327/// - `K = ()`: operates on a single default field,
1328///   meaning one virtual static field is assumed.
1329pub trait StaticFieldHelpers<K = ()>: VirtualStaticField<K>
1330where
1331    K: DiscriminantTag,
1332{
1333    /// Retrieves the full collection from the field interpreted as `Many`.
1334    ///
1335    /// ## Behavior
1336    /// - Returns `Some(V)` if the field is in `Many` form
1337    /// - Returns `None` if the field is `None` or `Some`
1338    fn get_all(&self) -> Option<Self::Many> {
1339        let repr = <Self as VirtualStaticField<K>>::access(self);
1340        TryIntoTag::<_, ManyTag>::try_into_tag(repr).ok()
1341    }
1342
1343    /// Sets the field to a collection (`Many`).
1344    ///
1345    /// ## Behavior
1346    /// - Replaces the entire field with the provided collection
1347    /// - No resizing or partial updates are performed
1348    fn set_all(&mut self, v: Self::Many)
1349    where
1350        Self::Many: Delimited,
1351    {
1352        <Self as VirtualStaticField<K>>::mutate(self, v.into_tag());
1353    }
1354
1355    /// Retrieves the value of the field interpreted as `Some`.
1356    ///
1357    /// ## Behavior
1358    /// - Returns `Some(V)` if the field contains a single value
1359    /// - Returns `None` otherwise
1360    fn get(&self) -> Option<Self::Some> {
1361        let repr = <Self as VirtualStaticField<K>>::access(self);
1362        TryIntoTag::<_, SomeTag>::try_into_tag(repr).ok()
1363    }
1364
1365    /// Sets the field to a single value (`Some`).
1366    ///
1367    /// Replaces any existing representation.
1368    fn set(&mut self, v: Self::Some)
1369    where
1370        Self::Some: Delimited,
1371    {
1372        <Self as VirtualStaticField<K>>::mutate(self, v.into_tag());
1373    }
1374}
1375
1376/// Blanket impl for all [`VirtualStaticField`] types.
1377///
1378/// This trait is not intended to be implemented manually.
1379/// It exists as an ergonomic replacement for free helper functions.
1380///
1381/// All methods have default implementations, making this
1382/// forward-compatible: new helpers can be added without
1383/// breaking existing code.
1384impl<T, K> StaticFieldHelpers<K> for T
1385where
1386    T: VirtualStaticField<K>,
1387    K: DiscriminantTag,
1388{
1389}
1390
1391// ===============================================================================
1392// ````````````````````````````` VIRTUAL FIELD-BOUNDS ````````````````````````````
1393// ===============================================================================
1394
1395/// Provides the bounds associated with a [`VirtualDynField<Discriminant>`].
1396///
1397/// `VirtualDynBound` defines constraints (such as capacity limits)
1398/// without requiring the field itself to hardcode them.
1399///
1400/// ## Representation
1401///
1402/// The bound is provided as a type implementing [`Get<u32>`],
1403/// meaning the value is **resolved at runtime (or via type-level indirection)**.
1404///
1405/// This enables flexible, dynamically bounded behavior while still
1406/// enforcing limits.
1407///
1408/// ## Discriminant
1409///
1410/// The `Discriminant` links a field to its corresponding bound,
1411/// allowing multiple independent fields to coexist without ambiguity.
1412///
1413/// ## Default Discriminant
1414///
1415/// - `Discriminant = ()`: provides a single default bound,
1416///   meaning only one dynamically bounded field is assumed.
1417pub trait VirtualDynBound<Discriminant: DiscriminantTag = ()> {
1418    type Bound: Get<u32> + Clone + Debug + 'static;
1419}
1420
1421/// No-op bound with zero capacity.
1422impl VirtualDynBound for () {
1423    type Bound = ConstU32<0>;
1424}
1425
1426/// Provides the bounds associated with a [`VirtualStaticField<Discriminant>`].
1427///
1428/// `VirtualStaticBound` defines constraints (such as capacity limits)
1429/// that are **fully determined at compile time**.
1430///
1431/// ## Representation
1432///
1433/// The bound is provided as a `const`, meaning:
1434/// - it is a **compile-time constant**
1435/// - no runtime resolution or indirection is involved
1436///
1437/// This enables fully static, zero-overhead representations.
1438///
1439/// ## Discriminant
1440///
1441/// The `Discriminant` links a field to its corresponding bound,
1442/// allowing multiple independent fields to coexist without ambiguity.
1443///
1444/// ## Default Discriminant
1445///
1446/// - `Discriminant = ()`: provides a single default bound,
1447///   meaning only one dynamically bounded field is assumed.
1448pub trait VirtualStaticBound<Discriminant: DiscriminantTag = ()> {
1449    const BOUND: usize;
1450}
1451/// No-op bound provided with zero capacity.
1452impl VirtualStaticBound for () {
1453    const BOUND: usize = 0;
1454}
1455
1456// ===============================================================================
1457// ```````````````````````````````` VIRTUAL ERRORS ```````````````````````````````
1458// ===============================================================================
1459
1460/// Defines the error type associated with a virtual component
1461/// identified by a `Discriminant`.
1462///
1463/// `VirtualError` provides a way to associate a specific error type
1464/// with a [`VirtualDynField`] or related abstraction, without hardcoding
1465/// the error into the implementation.
1466///
1467/// ## Discriminant
1468///
1469/// The `Discriminant` acts as a key linking a virtual field (or related
1470/// abstraction) to its corresponding error type.
1471///
1472/// This ensures multiple independent virtual components can coexist
1473/// without ambiguity.
1474///
1475/// ## Default Discriminant
1476///
1477/// - `Discriminant = ()`: associates a single default error type,
1478///   meaning only one virtual component is assumed.
1479pub trait VirtualError<Discriminant: DiscriminantTag = ()> {
1480    type Error: RuntimeError;
1481}
1482
1483// ===============================================================================
1484// ``````````````````````````` DELEGATED VIRTUAL BOUNDS ``````````````````````````
1485// ===============================================================================
1486
1487/// Delegates bound resolution to an external [`VirtualDynBound`] provider.
1488///
1489/// This trait is used when a type participates in a [`VirtualDynField`]
1490/// but does not define or own its bounds.
1491///
1492/// Instead, bounds are supplied externally via `Provider`,
1493/// allowing constraints (such as capacity) to be defined independently
1494/// of the field or its storage.
1495///
1496/// ## Representation
1497///
1498/// The delegated bound is a **runtime-resolved value** (via [`Get<u32>`]),
1499/// enabling flexible, dynamically bounded behavior.
1500///
1501/// ## Roles
1502///
1503/// - **Container (`Self`)**
1504///   - provides storage for the field
1505///
1506/// - **Bounds (`Provider`)**
1507///   - supplies constraints for that field
1508///
1509/// This separation enables:
1510/// - composability
1511/// - reuse across contexts
1512/// - decoupling of storage and constraints
1513///
1514/// ## Default Discriminant
1515///
1516/// - `Discriminant = ()`: delegates a single default bound,
1517///   meaning one dynamically bounded field is assumed.
1518pub trait DelegateVirtualDynBound<Provider, Discriminant = ()>
1519where
1520    Provider: VirtualDynBound<Discriminant>,
1521    Discriminant: DiscriminantTag,
1522    Self: Sized,
1523{
1524}
1525
1526/// Blanket implementation enabling all types to delegate
1527/// dynamic bound resolution to a [`VirtualDynBound`] provider.
1528impl<Provider, Discriminant, T> DelegateVirtualDynBound<Provider, Discriminant> for T
1529where
1530    Provider: VirtualDynBound<Discriminant>,
1531    Discriminant: DiscriminantTag,
1532    T: Sized,
1533{
1534}
1535
1536/// Delegates bound resolution to an external [`VirtualStaticBound`] provider.
1537///
1538/// This trait is used when a type participates in a [`VirtualStaticField`]
1539/// but does not define or own its bounds.
1540///
1541/// Instead, bounds are supplied externally via `Provider`,
1542/// allowing constraints (such as capacity) to be defined independently
1543/// of the field or its storage.
1544///
1545/// ## Representation
1546///
1547/// The delegated bound is a **compile-time constant** (`usize`),
1548/// enabling fully static, zero-overhead representations.
1549///
1550/// ## Roles
1551///
1552/// - **Container (`Self`)**
1553///   - provides storage for the field
1554///
1555/// - **Bounds (`Provider`)**
1556///   - supplies compile-time constraints for that field
1557///
1558/// This separation enables:
1559/// - composability
1560/// - reuse across contexts
1561/// - decoupling of storage and constraints
1562///
1563/// ## Default Discriminant
1564///
1565/// - `Discriminant = ()`: delegates a single default bound,
1566///   meaning one statically bounded field is assumed.
1567pub trait DelegateVirtualStaticBound<Provider, Discriminant = ()>
1568where
1569    Provider: VirtualStaticBound<Discriminant>,
1570    Discriminant: DiscriminantTag,
1571    Self: Sized,
1572{
1573}
1574
1575/// Blanket implementation enabling all types to delegate
1576/// static bound resolution to a [`VirtualStaticBound`] provider.
1577impl<Provider, Discriminant, T> DelegateVirtualStaticBound<Provider, Discriminant> for T
1578where
1579    Provider: VirtualStaticBound<Discriminant>,
1580    Discriminant: DiscriminantTag,
1581    T: Sized,
1582{
1583}
1584
1585// ===============================================================================
1586// ````````````````````` DELEGATED VIRTUAL FIELDS AND BOUNDS `````````````````````
1587// ===============================================================================
1588
1589/// Constraint describing a virtual field whose bounds are delegated
1590/// to an external [`VirtualDynBound`] provider.
1591///
1592/// This composes:
1593/// - [`VirtualDynField`] - defines storage and representation
1594/// - [`DelegateVirtualDynBound`] - supplies bounds externally
1595///
1596/// ## Semantics
1597///
1598/// - **Container (`Self`)**
1599///   - provides storage for values of type `T`
1600///
1601/// - **Bounds (`Provider`)**
1602///   - supplies capacity constraints
1603///
1604/// - **Caller**
1605///   - selects field shape (`None`, `Some`, `Many`)
1606///
1607/// ## Representation
1608///
1609/// Bounds are resolved dynamically:
1610/// - provided via [`Get<u32>`]
1611/// - enable flexible, vector-like behavior within limits
1612///
1613/// This allows storage and constraints to remain decoupled.
1614///
1615/// ## Default Discriminant
1616///
1617/// - `Discriminant = ()`: applies a single default bounded field,
1618///   meaning one dynamically bounded field is assumed.
1619pub trait VirtualDynFieldWithDelegatedBounds<T, Provider, Discriminant = ()>:
1620    VirtualDynField<Discriminant, Some = T> + DelegateVirtualDynBound<Provider, Discriminant>
1621where
1622    Provider: VirtualDynBound<Discriminant>,
1623    Discriminant: DiscriminantTag,
1624{
1625}
1626
1627/// Blanket implementation for any compatible container.
1628impl<T, Provider, Discriminant, U> VirtualDynFieldWithDelegatedBounds<T, Provider, Discriminant>
1629    for U
1630where
1631    U: VirtualDynField<Discriminant, Some = T> + DelegateVirtualDynBound<Provider, Discriminant>,
1632    Provider: VirtualDynBound<Discriminant>,
1633    Discriminant: DiscriminantTag,
1634{
1635}
1636
1637/// Constraint describing a virtual field whose bounds are delegated
1638/// to an external [`VirtualStaticBound`] provider.
1639///
1640/// This composes:
1641/// - [`VirtualStaticField`] - defines storage and representation
1642/// - [`DelegateVirtualStaticBound`] - supplies bounds externally
1643///
1644/// ## Semantics
1645///
1646/// - **Container (`Self`)**
1647///   - provides storage for values of type `T`
1648///
1649/// - **Bounds (`Provider`)**
1650///   - supplies compile-time capacity constraints
1651///
1652/// - **Caller**
1653///   - selects field shape (`None`, `Some`, `Many`)
1654///
1655/// ## Representation
1656///
1657/// Bounds are compile-time constants:
1658/// - encoded directly in the type system (`usize`)
1659/// - enable fixed-size, array-like behavior
1660///
1661/// This ensures fully static, zero-overhead representations.
1662///
1663/// ## Default Discriminant
1664///
1665/// - `Discriminant = ()`: applies a single default bounded field,
1666///   meaning one statically bounded field is assumed.
1667pub trait VirtualStaticFieldWithDelegatedBounds<T, Provider, Discriminant = ()>:
1668    VirtualStaticField<Discriminant, Some = T> + DelegateVirtualStaticBound<Provider, Discriminant>
1669where
1670    Provider: VirtualStaticBound<Discriminant>,
1671    Discriminant: DiscriminantTag,
1672{
1673}
1674
1675/// Blanket implementation for any compatible container.
1676impl<T, Provider, Discriminant, U> VirtualStaticFieldWithDelegatedBounds<T, Provider, Discriminant>
1677    for U
1678where
1679    U: VirtualStaticField<Discriminant, Some = T>
1680        + DelegateVirtualStaticBound<Provider, Discriminant>,
1681    Provider: VirtualStaticBound<Discriminant>,
1682    Discriminant: DiscriminantTag,
1683{
1684}
1685
1686// ===============================================================================
1687// `````````````````````````````` VIRTUAL EXTENSIONS `````````````````````````````
1688// ===============================================================================
1689
1690/// Defines the schema for a [`VirtualDynExtension`] identified by a `Discriminant`.
1691///
1692/// A `VirtualDynExtensionSchema` describes the **structure and representation**
1693/// of an extension field whose type is supplied externally.
1694///
1695/// Unlike [`VirtualDynField`], the element type and layout are not defined
1696/// by the container, but provided through this schema.
1697///
1698/// ## Context
1699///
1700/// In the virtual system:
1701/// - [`VirtualDynField`] defines fields with internally known types
1702/// - `VirtualDynExtensionSchema` defines fields with externally supplied types
1703/// - [`VirtualDynExtension`] stores values using this schema
1704///
1705/// This allows containers to support fields whose types are:
1706/// - not known at implementation time
1707/// - injected via type-level composition
1708///
1709/// ## Representation
1710///
1711/// The `Many` form is expected to have **vector-like semantics**:
1712/// - dynamically sized (within bounds)
1713/// - supports buffering and indexed access
1714///
1715/// The schema itself is purely type-level:
1716/// - it does not store data
1717/// - it defines how data is represented and interpreted
1718///
1719/// ## Discriminant
1720///
1721/// The `Discriminant` links:
1722/// - the extension storage
1723/// - to its schema
1724///
1725/// allowing multiple independent extensions to coexist safely.
1726///
1727/// ## Default Discriminant
1728///
1729/// - `Discriminant = ()`: defines a single default extension schema,
1730///   meaning only one extension is assumed.
1731pub trait VirtualDynExtensionSchema<Discriminant: DiscriminantTag = ()> {
1732    /// Representation of absence.
1733    type None: Delimited;
1734
1735    /// The logical element type defined by the schema.
1736    ///
1737    /// This type is externally supplied.
1738    type Some: Delimited;
1739
1740    /// A collection of `Some` with vector-like semantics.
1741    type Many: Buffer<Self::Some> + Indexable<Self::Some>;
1742
1743    /// Opaque representation of the extension.
1744    ///
1745    /// Encodes `None`, `Some`, or `Many` and supports tagged conversions.
1746    type Repr: Delimited
1747        // Initial empty representation
1748        + Default
1749        // Construct from absence
1750        + FromTag<Self::None, NoneTag>
1751        // Extract absence
1752        + TryIntoTag<Self::None, NoneTag>
1753        // Construct from single value
1754        + FromTag<Self::Some, SomeTag>
1755        // Extract single value
1756        + TryIntoTag<Self::Some, SomeTag>
1757        // Construct from many values (may fail due to bounds)
1758        + TryFromTag<Self::Many, ManyTag>
1759        // Convert into many values
1760        + IntoTag<Self::Many, ManyTag>;
1761
1762    /// Returns the number of elements encoded in the representation.
1763    fn len(v: &Self::Repr) -> usize;
1764
1765    /// Returns the minimum number of elements representable.
1766    fn min(v: &Self::Repr) -> usize;
1767
1768    /// Returns the maximum number of elements representable.
1769    fn max(v: &Self::Repr) -> usize;
1770}
1771
1772/// Defines the schema for a [`VirtualStaticExtension`] identified by a `Discriminant`.
1773///
1774/// A `VirtualStaticExtensionSchema` describes the **structure and representation**
1775/// of an extension field whose type is supplied externally and fully
1776/// determined at compile time.
1777///
1778/// ## Context
1779///
1780/// In the static field model:
1781/// - [`VirtualStaticField`] defines fields with fixed structure
1782/// - `VirtualStaticExtensionSchema` defines externally supplied types and layout
1783/// - [`VirtualStaticExtension`] stores values using this schema
1784///
1785/// This allows containers to support externally defined fields
1786/// with compile-time determined structure.
1787///
1788/// ## Representation
1789///
1790/// The `Many` form is expected to have **array-like semantics**:
1791/// - fixed size
1792/// - no dynamic resizing or allocation
1793/// - capacity encoded in the type
1794///
1795/// The schema is purely type-level:
1796/// - it does not store data
1797/// - it defines how data is represented and interpreted
1798///
1799/// ## Discriminant
1800///
1801/// The `Discriminant` links:
1802/// - the extension storage
1803/// - to its schema
1804///
1805/// allowing multiple independent extensions to coexist safely.
1806///
1807/// ## Default Discriminant
1808///
1809/// - `Discriminant = ()`: defines a single default extension schema,
1810///   meaning only one static extension is assumed.
1811pub trait VirtualStaticExtensionSchema<Discriminant: DiscriminantTag = ()> {
1812    /// Representation of absence.
1813    type None: Delimited;
1814
1815    /// The logical element type defined by the schema.
1816    ///
1817    /// This type is externally supplied.
1818    type Some: Delimited;
1819
1820    /// A fixed-size collection of `Some` with array-like semantics.
1821    type Many: Collection<Self::Some>;
1822
1823    /// Opaque representation of the extension.
1824    ///
1825    /// Encodes `None`, `Some`, or `Many` and supports tagged conversions.
1826    ///
1827    /// All conversions are expected to be total (non-fallible),
1828    /// as structure is fully determined at compile time.
1829    type Repr: Delimited
1830        // Initial representation
1831        + Default
1832        // Construct from absence
1833        + FromTag<Self::None, NoneTag>
1834        // Extract absence
1835        + TryIntoTag<Self::None, NoneTag>
1836        // Construct from single value
1837        + FromTag<Self::Some, SomeTag>
1838        // Extract single value
1839        + TryIntoTag<Self::Some, SomeTag>
1840        // Construct from many values (total)
1841        + FromTag<Self::Many, ManyTag>
1842        // Extract many values (total)
1843        + TryIntoTag<Self::Many, ManyTag>;
1844}
1845
1846/// Allocation interface for virtual extensions whose type and schema
1847/// are defined externally.
1848///
1849/// This is a second-order abstraction over [`VirtualDynField`]:
1850/// instead of defining its own element type, the field delegates both
1851/// type and representation to an external schema.
1852///
1853/// ## Context
1854///
1855/// In the virtual system:
1856/// - [`VirtualDynField`] defines fields with internally known types
1857/// - [`VirtualDynExtensionSchema`] defines externally supplied types and layout
1858/// - `VirtualDynExtension` stores values using that schema
1859///
1860/// This allows a container (`Self`) to host fields whose types are:
1861/// - not known at implementation time
1862/// - supplied later via type-level composition
1863///
1864/// ## Representation
1865///
1866/// All operations are performed on the schema-defined representation:
1867/// - `TypesVia` defines `None`, `Some`, `Many`, and `Repr`
1868/// - `Many` is expected to have **vector-like semantics**
1869/// - size and bounds are resolved dynamically (within constraints)
1870///
1871/// ## Semantics
1872///
1873/// - **Container (`Self`)**
1874///   - owns storage
1875///
1876/// - **Schema (`TypesVia`)**
1877///   - defines element type and representation
1878///
1879/// This enables fields to remain fully generic over externally
1880/// defined and deferred types.
1881///
1882/// ## Key Property
1883///
1884/// Type and structure are **not fixed in the container**, but injected
1885/// externally and resolved at compile time.
1886///
1887/// ## Default Discriminant
1888///
1889/// - `Discriminant = ()`: defines a single default extension,
1890///   meaning only one dynamic extension is assumed.
1891pub trait VirtualDynExtension<Discriminant: DiscriminantTag = ()>: Default {
1892    /// External schema defining the extension.
1893    type TypesVia: VirtualDynExtensionSchema<Discriminant>;
1894
1895    /// Returns the underlying representation.
1896    fn access(&self) -> <Self::TypesVia as VirtualDynExtensionSchema<Discriminant>>::Repr;
1897
1898    /// Replaces the underlying representation.
1899    fn mutate(&mut self, v: <Self::TypesVia as VirtualDynExtensionSchema<Discriminant>>::Repr);
1900
1901    /// Returns the current number of elements.
1902    fn len(&self) -> usize {
1903        <Self::TypesVia as VirtualDynExtensionSchema<Discriminant>>::len(&Self::access(&self))
1904    }
1905
1906    /// Returns the minimum number of elements representable.
1907    fn min(&self) -> usize {
1908        <Self::TypesVia as VirtualDynExtensionSchema<Discriminant>>::min(&Self::access(&self))
1909    }
1910
1911    /// Returns the maximum number of elements representable.
1912    fn max(&self) -> usize {
1913        <Self::TypesVia as VirtualDynExtensionSchema<Discriminant>>::max(&Self::access(&self))
1914    }
1915}
1916
1917/// Allocation interface for virtual extensions whose type and schema
1918/// are defined externally and fully determined at compile time.
1919///
1920/// This is the static counterpart to [`VirtualDynExtension`], where
1921/// both type and structure are fixed via the schema.
1922///
1923/// ## Context
1924///
1925/// In the static field model:
1926/// - [`VirtualStaticField`] defines fields with fixed structure
1927/// - [`VirtualStaticExtensionSchema`] defines externally supplied types
1928///   and compile-time layout
1929/// - `VirtualStaticExtension` stores values using that schema
1930///
1931/// This allows a container (`Self`) to host externally defined fields
1932/// with statically determined structure.
1933///
1934/// ## Representation
1935///
1936/// All operations are performed on the schema-defined representation:
1937/// - `TypesVia` defines `None`, `Some`, `Many`, and `Repr`
1938/// - `Many` is expected to have **array-like semantics**
1939/// - size and capacity are encoded at compile time
1940///
1941/// ## Semantics
1942///
1943/// - **Container (`Self`)**
1944///   - owns storage
1945///
1946/// - **Schema (`TypesVia`)**
1947///   - defines element type and representation
1948///
1949/// ## Key Property
1950///
1951/// Both type and structure are **fully determined at compile time**,
1952/// enabling zero-overhead representations without dynamic checks.
1953///
1954/// ## Default Discriminant
1955///
1956/// - `Discriminant = ()`: defines a single default extension,
1957///   meaning only one static extension is assumed.
1958pub trait VirtualStaticExtension<Discriminant: DiscriminantTag = ()>: Default {
1959    /// External schema defining the extension.
1960    type TypesVia: VirtualStaticExtensionSchema<Discriminant>;
1961
1962    /// Returns the underlying representation.
1963    fn access(&self) -> <Self::TypesVia as VirtualStaticExtensionSchema<Discriminant>>::Repr;
1964
1965    /// Replaces the underlying representation.
1966    fn mutate(&mut self, v: <Self::TypesVia as VirtualStaticExtensionSchema<Discriminant>>::Repr);
1967}
1968
1969// ===============================================================================
1970// `````````````````````` VIRTUAL EXTENSION DEFAULT-HELPERS ``````````````````````
1971// ===============================================================================
1972
1973/// Helper methods for accessing and mutating values in a [`VirtualDynExtension`].
1974///
1975/// These helpers operate on **dynamically shaped extensions** with
1976/// **vector-like semantics**:
1977/// - collections may grow or shrink (within bounds)
1978/// - indexing and iteration are supported
1979/// - mutations may fail due to constraints
1980///
1981/// Structure and types are defined externally via [`VirtualDynExtensionSchema`],
1982/// while storage is handled by the container.
1983///
1984/// All operations are performed via tagged conversions.
1985///
1986/// ## Default Discriminant
1987///
1988/// - `K = ()`: operates on a single default extension,
1989///   meaning one dynamic extension is assumed.
1990pub trait DynExtHelpers<K = ()>: VirtualDynExtension<K>
1991where
1992    K: DiscriminantTag,
1993{
1994    /// Returns the element at `index` from the extension interpreted as `Many`.
1995    fn index_get(
1996        &self,
1997        index: usize,
1998    ) -> Option<<Self::TypesVia as VirtualDynExtensionSchema<K>>::Some>
1999    where
2000        <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some: Clone,
2001    {
2002        <Self as VirtualDynExtension<K>>::access(self)
2003            .into_tag()
2004            .as_ref()
2005            .get(index)
2006            .cloned()
2007    }
2008
2009    /// Returns an iterator over elements.
2010    fn iter(&self) -> impl Iterator<Item = <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some>
2011    where
2012        <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some: Clone,
2013    {
2014        <Self as VirtualDynExtension<K>>::access(self)
2015            .into_tag()
2016            .into_iter()
2017    }
2018
2019    /// Applies mutation over all elements.
2020    fn iter_mut<F>(&mut self, mut f: F) -> Result<(), ()>
2021    where
2022        F: FnMut(&mut <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some),
2023    {
2024        let mut repr = <Self as VirtualDynExtension<K>>::access(self).into_tag();
2025
2026        let len = repr.as_ref().len();
2027        for i in 0..len {
2028            f(&mut repr[i]);
2029        }
2030
2031        let repr = TryFromTag::try_from_tag(repr).map_err(|_| ())?;
2032        <Self as VirtualDynExtension<K>>::mutate(self, repr);
2033
2034        Ok(())
2035    }
2036
2037    /// Sets element at index.
2038    fn index_set(
2039        &mut self,
2040        index: usize,
2041        v: <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some,
2042    ) -> Result<(), ()>
2043    where
2044        <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some: Default,
2045    {
2046        let mut repr = <Self as VirtualDynExtension<K>>::access(self).into_tag();
2047
2048        set_index(&mut repr, index, v);
2049
2050        let repr = TryFromTag::try_from_tag(repr).map_err(|_| ())?;
2051        <Self as VirtualDynExtension<K>>::mutate(self, repr);
2052
2053        Ok(())
2054    }
2055
2056    /// Retrieves `Some`.
2057    fn get(&self) -> Option<<Self::TypesVia as VirtualDynExtensionSchema<K>>::Some> {
2058        let repr = <Self as VirtualDynExtension<K>>::access(self);
2059        TryIntoTag::<_, SomeTag>::try_into_tag(repr).ok()
2060    }
2061
2062    /// Sets `Some`.
2063    fn set(&mut self, v: <Self::TypesVia as VirtualDynExtensionSchema<K>>::Some) {
2064        <Self as VirtualDynExtension<K>>::mutate(self, v.into_tag());
2065    }
2066}
2067
2068/// Blanket impl for all [`VirtualDynExtension`] types.
2069///
2070/// This trait is not intended to be implemented manually.
2071/// It exists as an ergonomic replacement for free helper functions.
2072///
2073/// All methods have default implementations, making this
2074/// forward-compatible: new helpers can be added without
2075/// breaking existing code.
2076impl<T, K> DynExtHelpers<K> for T
2077where
2078    T: VirtualDynExtension<K>,
2079    K: DiscriminantTag,
2080{
2081}
2082
2083/// Helper methods for accessing and mutating values in a [`VirtualStaticExtension`].
2084///
2085/// These helpers operate on **statically shaped extensions** with
2086/// **array-like semantics**:
2087/// - collection size is fixed at compile time
2088/// - no resizing or extension is performed
2089/// - operations act on the entire structure
2090///
2091/// Structure and types are defined externally via [`VirtualStaticExtensionSchema`],
2092/// while storage is handled by the container.
2093///
2094/// All operations are performed via tagged conversions.
2095///
2096/// ## Default Discriminant
2097///
2098/// - `K = ()`: operates on a single default extension,
2099///   meaning one static extension is assumed.
2100pub trait StaticExtHelpers<K = ()>: VirtualStaticExtension<K>
2101where
2102    K: DiscriminantTag,
2103{
2104    /// Retrieves the full collection (`Many`).
2105    fn get_all(&self) -> Option<<Self::TypesVia as VirtualStaticExtensionSchema<K>>::Many> {
2106        let repr = <Self as VirtualStaticExtension<K>>::access(self);
2107        TryIntoTag::<_, ManyTag>::try_into_tag(repr).ok()
2108    }
2109
2110    /// Sets full collection.
2111    fn set_all(&mut self, v: <Self::TypesVia as VirtualStaticExtensionSchema<K>>::Many)
2112    where
2113        <Self::TypesVia as VirtualStaticExtensionSchema<K>>::Many: Delimited,
2114    {
2115        <Self as VirtualStaticExtension<K>>::mutate(self, v.into_tag());
2116    }
2117
2118    /// Retrieves `Some`.
2119    fn get(&self) -> Option<<Self::TypesVia as VirtualStaticExtensionSchema<K>>::Some> {
2120        let repr = <Self as VirtualStaticExtension<K>>::access(self);
2121        TryIntoTag::<_, SomeTag>::try_into_tag(repr).ok()
2122    }
2123
2124    /// Sets `Some`.
2125    fn set(&mut self, v: <Self::TypesVia as VirtualStaticExtensionSchema<K>>::Some) {
2126        <Self as VirtualStaticExtension<K>>::mutate(self, v.into_tag());
2127    }
2128}
2129
2130/// Blanket impl for all [`VirtualStaticExtension`] types.
2131///
2132/// This trait is not intended to be implemented manually.
2133/// It exists as an ergonomic replacement for free helper functions.
2134///
2135/// All methods have default implementations, making this
2136/// forward-compatible: new helpers can be added without
2137/// breaking existing code.
2138impl<T, K> StaticExtHelpers<K> for T
2139where
2140    T: VirtualStaticExtension<K>,
2141    K: DiscriminantTag,
2142{
2143}
2144
2145/// Sets the value at a given index in a collection.
2146///
2147/// If the index is out of bounds, the collection is automatically extended
2148/// with default values (`T::default()`) up to the required index.
2149///
2150/// ## Behavior
2151/// - If `index < current length`, the value is simply updated.
2152/// - If `index >= current length`, the collection is resized by filling
2153///   missing positions with default values, then the value is set.
2154///
2155/// ## Type Parameters
2156/// - `C`: A collection that supports indexing and extension.
2157/// - `T`: The element type, which must implement `Default`.
2158///
2159/// ## Example
2160/// If the collection has length 3 and you set index 5:
2161/// - Elements at index 3 and 4 will be filled with `T::default()`.
2162/// - Index 5 will be assigned the given `value`.
2163fn set_index<C, T>(v: &mut C, index: usize, value: T)
2164where
2165    C: Indexable<T> + Growable<T>,
2166    T: Default,
2167{
2168    let len = v.as_ref().len();
2169    if index >= len {
2170        v.extend(core::iter::repeat_with(T::default).take(index + 1 - len));
2171    }
2172    v[index] = value;
2173}
2174
2175/// Implements an empty virtual extension schema for a given extension.
2176///
2177/// This macro defines a no-op schema where the extension has **no storage**
2178/// and behaves as absent.
2179///
2180/// It supports two modes:
2181///
2182/// - **Dynamic (default)** -> implements [`VirtualDynExtensionSchema`]
2183///   - uses vector-like semantics (`Vec<()>`)
2184///   - size-related operations (`len`, `min`, `max`) return `0`
2185///
2186/// - **Static (`static` keyword)** -> implements [`VirtualStaticExtensionSchema`]
2187///   - uses array-like semantics (`[(); 0]`)
2188///   - fully determined at compile time
2189///   - no size-related operations are required
2190///
2191/// ## Semantics
2192///
2193/// In both modes:
2194/// - `None`, `Some`, and `Repr` are represented as `()`
2195/// - no data is stored
2196/// - the extension is effectively non-existent
2197///
2198/// This is useful when:
2199/// - a container participates in the extension system
2200/// - but a particular extension is unsupported or intentionally omitted
2201///
2202/// ## Syntax
2203///
2204/// ### Dynamic (default)
2205/// ```ignore
2206/// empty_virtual_extension!(
2207///     target: MyContainer,
2208///     tag: MyExtension,
2209///     schema: MySchema,
2210///     generics: [T, U],
2211///     bounds: [T: Clone, U: Default],
2212/// );
2213/// ```
2214///
2215/// ### Static
2216/// ```ignore
2217/// empty_virtual_extension!(
2218///     target: MyContainer,
2219///     tag: MyExtension,
2220///     schema: static MySchema,
2221/// );
2222/// ```
2223///
2224/// ## Parameters
2225///
2226/// - `target`: container type (conceptual owner of the extension)
2227/// - `tag`: discriminant identifying the extension
2228/// - `schema`: schema type to implement
2229/// - `generics` *(optional)*: generics for the impl
2230/// - `bounds` *(optional)*: additional `where` constraints
2231///
2232/// ## Behavior
2233///
2234/// - The extension is treated as non-existent
2235/// - Dynamic mode:
2236///   - uses `Vec<()>` (always empty)
2237///   - returns `0` for all size queries
2238/// - Static mode:
2239///   - uses `[(); 0]` (zero-length array)
2240///   - fully resolved at compile time
2241#[macro_export]
2242macro_rules! empty_virtual_extension {
2243    // STATIC VERSION
2244    (
2245        target: $target:ty,
2246        tag: $extension:ty,
2247        schema: static $schema:ty
2248        $(, generics: [$($gen:tt),* $(,)? ])?
2249        $(, bounds: [$($extra_bounds:tt)*])?
2250        $(,)?
2251    ) => {
2252        impl< $($($gen,)*)? >
2253            $crate::virtuals::VirtualStaticExtensionSchema<$extension>
2254            for $schema
2255        where
2256            $($($extra_bounds)*)?
2257        {
2258            type None = ();
2259            type Some = ();
2260            type Many = [(); 0];
2261            type Repr = ();
2262        }
2263    };
2264
2265    // DYNAMIC VERSION (default)
2266    (
2267        target: $target:ty,
2268        tag: $extension:ty,
2269        schema: $schema:ty
2270        $(, generics: [$($gen:tt),* $(,)? ])?
2271        $(, bounds: [$($extra_bounds:tt)*])?
2272        $(,)?
2273    ) => {
2274        impl< $($($gen,)*)? >
2275            $crate::virtuals::VirtualDynExtensionSchema<$extension>
2276            for $schema
2277        where
2278            $($($extra_bounds)*)?
2279        {
2280            type None = ();
2281            type Some = ();
2282            type Many = Vec<()>;
2283            type Repr = ();
2284
2285            fn len(_: &Self::Repr) -> usize {
2286                Zero::zero()
2287            }
2288
2289            fn min(_: &Self::Repr) -> usize {
2290                Zero::zero()
2291            }
2292
2293            fn max(_: &Self::Repr) -> usize {
2294                Zero::zero()
2295            }
2296        }
2297    };
2298}
2299
2300// ===============================================================================
2301// ````````````````````````` DELEGATED VIRTUAL EXTENSIONS ````````````````````````
2302// ===============================================================================
2303
2304/// Constraint for delegating a virtual extension to an external schema.
2305///
2306/// This trait ties a container to an externally provided
2307/// [`VirtualDynExtensionSchema`], without requiring the container
2308/// to define the extension's type or representation itself.
2309///
2310/// ## Roles
2311///
2312/// - **Container (`Self`)**
2313///   - stores the extension representation
2314///
2315/// - **Schema (`Provider`)**
2316///   - defines the element type and representation
2317///
2318/// - **Caller**
2319///   - selects the extension via the `Discriminant`
2320///
2321/// ## Representation
2322///
2323/// The delegated schema is dynamic:
2324/// - `Many` has vector-like semantics
2325/// - size and bounds are resolved at runtime (within limits)
2326///
2327/// ## Default Discriminant
2328///
2329/// - `Discriminant = ()`: delegates a single default extension,
2330///   meaning one dynamic extension is assumed.
2331pub trait DelegateVirtualDynExtension<Provider, Discriminant = ()>:
2332    VirtualDynExtension<Discriminant>
2333where
2334    Provider: VirtualDynExtensionSchema<Discriminant>,
2335    Discriminant: DiscriminantTag,
2336    Self: Sized,
2337{
2338}
2339
2340/// Blanket implementation enabling all types to delegate
2341/// extension schema resolution.
2342impl<Provider, Discriminant, T> DelegateVirtualDynExtension<Provider, Discriminant> for T
2343where
2344    T: VirtualDynExtension<Discriminant> + Sized,
2345    Discriminant: DiscriminantTag,
2346    Provider: VirtualDynExtensionSchema<Discriminant>,
2347{
2348}
2349
2350/// Constraint for delegating a virtual extension to an external
2351/// [`VirtualStaticExtensionSchema`].
2352///
2353/// This is the static counterpart to [`DelegateVirtualDynExtension`],
2354/// where the schema defines a fully determined, compile-time structure.
2355///
2356/// ## Roles
2357///
2358/// - **Container (`Self`)**
2359///   - stores the extension representation
2360///
2361/// - **Schema (`Provider`)**
2362///   - defines the element type and representation
2363///
2364/// - **Caller**
2365///   - selects the extension via the `Discriminant`
2366///
2367/// ## Representation
2368///
2369/// The delegated schema is static:
2370/// - `Many` has array-like semantics
2371/// - size and capacity are fixed at compile time
2372///
2373/// ## Default Discriminant
2374///
2375/// - `Discriminant = ()`: delegates a single default extension,
2376///   meaning one static extension is assumed.
2377pub trait DelegateVirtualStaticExtension<Provider, Discriminant = ()>:
2378    VirtualStaticExtension<Discriminant>
2379where
2380    Provider: VirtualStaticExtensionSchema<Discriminant>,
2381    Discriminant: DiscriminantTag,
2382    Self: Sized,
2383{
2384}
2385
2386/// Blanket implementation enabling all types to delegate
2387/// static extension schema resolution.
2388impl<Provider, Discriminant, T> DelegateVirtualStaticExtension<Provider, Discriminant> for T
2389where
2390    T: VirtualStaticExtension<Discriminant> + Sized,
2391    Discriminant: DiscriminantTag,
2392    Provider: VirtualStaticExtensionSchema<Discriminant>,
2393{
2394}
2395
2396// ===============================================================================
2397// `````````````````````````````` VIRTUAL COLLECTOR ``````````````````````````````
2398// ===============================================================================
2399
2400/// A virtual collector for values of type `T` under a discriminant.
2401///
2402/// A `VirtualCollector` represents a type that can:
2403/// - collect a value `T` into itself (via [`FromTag`])
2404/// - attempt to extract a value `T` back (via [`TryIntoTag`])
2405///
2406/// ## Virtual Field Context
2407///
2408/// In the virtual system:
2409/// - values may be interpreted differently depending on their role
2410/// - tagged conversions (`FromTag`, `TryIntoTag`) define those interpretations
2411/// - this trait groups types that support bidirectional interaction with `T`
2412///
2413/// ## Semantics
2414///
2415/// A `VirtualCollector` acts as a *tagged carrier* of `T`:
2416///
2417/// - `T -> Self`
2418///   - always succeeds (collection)
2419///
2420/// - `Self -> T`
2421///   - may fail depending on structure (extraction)
2422///
2423/// This is commonly implemented by enums where a specific variant
2424/// represents `T`.
2425///
2426/// ## Example Pattern
2427///
2428/// ```ignore
2429/// enum Value {
2430///     Number(u32),
2431///     Text(String),
2432/// }
2433///
2434/// // `Value` can act as a VirtualCollector<u32>
2435/// ```
2436///
2437/// ## Discriminant
2438///
2439/// The `Discriminant` ensures conversions remain unambiguous,
2440/// even when `T` or `Self` are generic or not fully concrete.
2441///
2442/// ## When to Use
2443///
2444/// Use this trait when:
2445/// - a type can *collect* values of `T`
2446/// - extraction may depend on internal structure
2447/// - tagged semantics are required for disambiguation
2448///
2449/// ## Default Discriminant
2450///
2451/// - `Discriminant = ()`: defines a single default interpretation,
2452///   meaning one collection/extraction behavior is assumed.
2453pub trait VirtualCollector<T, Discriminant: DiscriminantTag = ()>:
2454    FromTag<T, Discriminant> + TryIntoTag<T, Discriminant>
2455{
2456}
2457
2458/// Blanket implementation for all types supporting bidirectional tagged
2459/// conversion with `T`.
2460///
2461/// Any type that:
2462/// - can be constructed from `T` via [`FromTag`]
2463/// - can attempt to extract `T` via [`TryIntoTag`]
2464///
2465/// automatically implements [`VirtualCollector`].
2466///
2467/// This allows enums and similar container types to act as collectors
2468/// without requiring explicit implementations.
2469impl<T, Discriminant, U> VirtualCollector<T, Discriminant> for U
2470where
2471    U: FromTag<T, Discriminant> + TryIntoTag<T, Discriminant>,
2472    Discriminant: DiscriminantTag,
2473{
2474}
2475
2476// ===============================================================================
2477// ````````````````````````````` VIRTUAL STORAGE MAPS ````````````````````````````
2478// ===============================================================================
2479
2480/// A storage-backed virtual n-map owned by a container in the virtual structure system.
2481///
2482/// This trait defines a **map-like virtual component** that is logically owned
2483/// by a container (`For`), while its storage is delegated to an external
2484/// implementation (e.g. [`StorageNMap`]).
2485///
2486/// ## Virtual Structure Context
2487///
2488/// In the virtual system, a container (virtual struct) composes behavior through
2489/// independent, type-driven components:
2490///
2491/// - [`VirtualDynField`] / [`VirtualStaticField`] - field-level abstraction
2492/// over values and cardinality
2493/// - [`VirtualDynExtension`] / [`VirtualStaticExtension`] - externally defined
2494/// field schemas
2495/// - `VirtualNMap` - container-level map storage
2496///
2497/// These components are:
2498/// - **logically part of the container**
2499/// - but **not required to share a single physical representation**
2500///
2501/// ## Ownership and Delegation
2502///
2503/// The container (`For`) acts as the **owner** of the map:
2504/// - it defines the type context (e.g. key/value via associated types)
2505/// - it determines how the map is used
2506/// - but it does not store the map directly
2507///
2508/// Instead, storage is delegated to a native map implementation.
2509///
2510/// This separation allows:
2511/// - lightweight container representations
2512/// - efficient handling of large or frequently mutated data
2513/// - independent evolution of storage and structure
2514///
2515/// ## Type-Level Association
2516///
2517/// - `For`: the owning container (virtual struct)
2518/// - `Discriminant`: a type-level key identifying this map
2519///
2520/// This enables:
2521/// - multiple independent maps per container
2522/// - map definitions derived from container-level abstractions
2523/// - coherence-safe composition via distinct discriminants
2524///
2525/// ## Storage Model
2526///
2527/// - storage is provided by the implementor via [`StorageNMap`]
2528/// - keys are encoded using [`KeyGenerator`]
2529/// - iteration and prefix-based access are supported
2530///
2531/// The map is external in storage, but internal in ownership and usage.
2532///
2533/// ## When to Use
2534///
2535/// Use this trait when:
2536/// - a container logically owns map-like data
2537/// - key/value types depend on container-level abstractions
2538/// - data is large, dynamic, or frequently mutated
2539/// - embedding the map in a virtual field or representation is inefficient
2540///
2541/// ## Default Discriminant
2542///
2543/// - `Discriminant = ()`: defines a single default map,
2544///   meaning one virtual map is assumed per container.
2545pub trait VirtualNMap<For: Delimited, Discriminant: DiscriminantTag = ()> {
2546    /// Key used to address entries in the map.
2547    ///
2548    /// Must:
2549    /// - match the input shape expected by `KeyGen::KArg`
2550    /// - support tuple-style encoding for multi-key storage
2551    /// - allow iteration over encoded components
2552    type Key: Delimited + EncodeLikeTuple<<Self::KeyGen as KeyGenerator>::KArg> + TupleToEncodedIter;
2553
2554    /// Value stored in the map.
2555    ///
2556    /// Typically represents externally stored data associated with the container.
2557    type Value: Delimited;
2558
2559    /// Defines how `Key` is transformed into storage keys.
2560    ///
2561    /// Supports:
2562    /// - forward encoding into storage
2563    /// - reverse decoding for iteration and prefix traversal
2564    type KeyGen: KeyGenerator + ReversibleKeyGenerator;
2565
2566    /// Underlying storage map backing this abstraction.
2567    ///
2568    /// Must support:
2569    /// - basic CRUD operations
2570    /// - full iteration
2571    /// - prefix-based queries and draining
2572    type Map: StorageNMap<Self::KeyGen, Self::Value, Query = Self::Query>
2573        + IterableStorageNMap<Self::KeyGen, Self::Value, Query = Self::Query>
2574        + StoragePrefixedMap<Self::Value>;
2575
2576    /// Return type for read operations.
2577    ///
2578    /// Encodes presence/absence semantics (e.g. `Option<Value>`).
2579    type Query;
2580
2581    /// Fetch value associated with `key`.
2582    #[inline]
2583    fn get(key: Self::Key) -> Self::Query {
2584        Self::Map::get(key)
2585    }
2586
2587    /// Insert or overwrite value at `key`.
2588    #[inline]
2589    fn insert(key: Self::Key, value: Self::Value) {
2590        Self::Map::insert(key, value)
2591    }
2592
2593    /// Remove value at `key`.
2594    #[inline]
2595    fn remove(key: Self::Key) {
2596        Self::Map::remove(key)
2597    }
2598
2599    /// Remove and return value at `key`.
2600    #[inline]
2601    fn take(key: Self::Key) -> Self::Query {
2602        Self::Map::take(key)
2603    }
2604
2605    /// Check if `key` exists.
2606    #[inline]
2607    fn contains_key(key: Self::Key) -> bool {
2608        Self::Map::contains_key(key)
2609    }
2610
2611    /// Mutate value at `key` in-place.
2612    ///
2613    /// Provides `Option<Value>` to handle both insert/update/remove cases.
2614    #[inline]
2615    fn mutate<R>(key: Self::Key, f: impl FnOnce(&mut Option<Self::Value>) -> R) -> R {
2616        Self::Map::mutate_exists(key, f)
2617    }
2618
2619    /// Iterate over all `(full_key, value)` pairs.
2620    #[inline]
2621    fn iter() -> impl Iterator<Item = (<Self::KeyGen as KeyGenerator>::Key, Self::Value)> {
2622        Self::Map::iter()
2623    }
2624
2625    /// Iterate over all full keys.
2626    #[inline]
2627    fn iter_keys() -> impl Iterator<Item = <Self::KeyGen as KeyGenerator>::Key> {
2628        Self::Map::iter_keys()
2629    }
2630
2631    /// Iterate over all values.
2632    #[inline]
2633    fn iter_values() -> impl Iterator<Item = Self::Value> {
2634        Self::Map::iter_values()
2635    }
2636
2637    /// Drain entire map, yielding all `(key, value)` pairs.
2638    #[inline]
2639    fn drain() -> impl Iterator<Item = (<Self::KeyGen as KeyGenerator>::Key, Self::Value)> {
2640        Self::Map::drain()
2641    }
2642
2643    /// Count total number of entries.
2644    #[inline]
2645    fn count() -> usize {
2646        Self::Map::iter_keys().count()
2647    }
2648
2649    /// Iterate over values matching a prefix.
2650    ///
2651    /// Prefix corresponds to a partial key (leading components).
2652    #[inline]
2653    fn iter_prefix_values<P>(prefix: P) -> impl Iterator<Item = Self::Value>
2654    where
2655        Self::KeyGen: HasKeyPrefix<P>,
2656    {
2657        Self::Map::iter_prefix_values(prefix)
2658    }
2659
2660    /// Iterate over `(suffix, value)` under a prefix.
2661    ///
2662    /// `suffix` = remaining key components after the prefix.
2663    #[inline]
2664    fn iter_prefix<P>(
2665        prefix: P,
2666    ) -> impl Iterator<Item = (<Self::KeyGen as HasKeyPrefix<P>>::Suffix, Self::Value)>
2667    where
2668        Self::KeyGen: HasReversibleKeyPrefix<P>,
2669    {
2670        Self::Map::iter_prefix(prefix)
2671    }
2672
2673    /// Iterate over suffix keys under a prefix.
2674    #[inline]
2675    fn iter_key_prefix<P>(
2676        prefix: P,
2677    ) -> impl Iterator<Item = <Self::KeyGen as HasKeyPrefix<P>>::Suffix>
2678    where
2679        Self::KeyGen: HasReversibleKeyPrefix<P>,
2680    {
2681        Self::Map::iter_key_prefix(prefix)
2682    }
2683
2684    /// Drain entries under a prefix, yielding `(suffix, value)`.
2685    #[inline]
2686    fn drain_prefix<P>(
2687        prefix: P,
2688    ) -> impl Iterator<Item = (<Self::KeyGen as HasKeyPrefix<P>>::Suffix, Self::Value)>
2689    where
2690        Self::KeyGen: HasReversibleKeyPrefix<P>,
2691    {
2692        Self::Map::drain_prefix(prefix)
2693    }
2694}
2695
2696/// A storage-backed virtual map owned by a container in the virtual structure system.
2697///
2698/// This trait defines a **map-like virtual component** that is logically owned
2699/// by a container (`For`), while its storage is delegated to an external
2700/// implementation (e.g. [`StorageMap`]).
2701///
2702/// ## Virtual Structure Context
2703///
2704/// In the virtual system, a container (virtual struct) composes behavior through
2705/// independent, type-driven components:
2706///
2707/// - [`VirtualDynField`] / [`VirtualStaticField`] - field-level abstraction
2708/// over values and cardinality
2709/// - [`VirtualDynExtension`] / [`VirtualStaticExtension`] - externally defined
2710/// field schemas
2711/// - `VirtualMap` - container-level map storage
2712///
2713/// These components are logically part of the container, but are not required
2714/// to share a single physical representation.
2715///
2716/// ## Ownership and Delegation
2717///
2718/// The container (`For`) acts as the **owner** of the map:
2719/// - it provides the type context for the map (key/value via associated types)
2720/// - it determines how the map is used
2721/// - but it does not store the map directly
2722///
2723/// Instead, storage is delegated to a native map implementation.
2724///
2725/// This allows:
2726/// - avoiding encode/decode overhead from embedding maps in representations
2727/// - efficient handling of large or frequently mutated data
2728/// - separation of structure (types) from storage (runtime)
2729///
2730/// ## Type-Level Association
2731///
2732/// - `For`: the owning container (virtual struct)
2733/// - `Discriminant`: a type-level key identifying this map
2734///
2735/// This enables:
2736/// - multiple independent maps per container
2737/// - map definitions derived from container-level abstractions
2738/// - coherence-safe composition via distinct discriminants
2739///
2740/// ## Storage Model
2741///
2742/// - storage is provided by the implementor via [`StorageMap`]
2743/// - keys are encoded via [`KeyGenerator`]
2744/// - iteration and full traversal are supported
2745///
2746/// The map is external in storage, but internal in ownership and usage.
2747///
2748/// ## When to Use
2749///
2750/// Use this trait when:
2751/// - a container logically owns map-like data
2752/// - key/value types depend on container-level abstractions
2753/// - data is large, dynamic, or frequently mutated
2754/// - embedding the map in a virtual field or representation is inefficient
2755///
2756/// ## Default Discriminant
2757///
2758/// - `Discriminant = ()`: defines a single default map,
2759///   meaning one virtual map is assumed per container.
2760pub trait VirtualMap<For: Delimited, Discriminant: DiscriminantTag = ()> {
2761    /// Key used to address entries in the map.
2762    ///
2763    /// Must:
2764    /// - be encodable in the same form as `KeyGen`
2765    /// - support iteration over encoded components (for uniform handling)
2766    type Key: Delimited + EncodeLike<Self::KeyGen> + TupleToEncodedIter;
2767
2768    /// Value stored in the map.
2769    ///
2770    /// Represents externally stored data associated with the container.
2771    type Value: Delimited;
2772
2773    /// Defines how keys are encoded into storage and decoded back.
2774    ///
2775    /// Supports:
2776    /// - forward encoding into storage keys
2777    /// - reverse decoding during iteration
2778    type KeyGen: KeyGenerator + ReversibleKeyGenerator + EncodeLike;
2779
2780    /// Underlying storage map backing this abstraction.
2781    ///
2782    /// Must support:
2783    /// - basic CRUD operations
2784    /// - full iteration over keys and values
2785    /// - prefixed storage layout
2786    type Map: StorageMap<Self::KeyGen, Self::Value, Query = Self::Query>
2787        + IterableStorageMap<Self::KeyGen, Self::Value, Query = Self::Query>
2788        + StoragePrefixedMap<Self::Value>;
2789
2790    /// Return type for read operations.
2791    ///
2792    /// Typically `Option<Value>` or a query wrapper.
2793    type Query;
2794
2795    /// Fetch value associated with `key`.
2796    #[inline]
2797    fn get(key: Self::Key) -> Self::Query {
2798        Self::Map::get(key)
2799    }
2800
2801    /// Insert or overwrite value at `key`.
2802    #[inline]
2803    fn insert(key: Self::Key, value: Self::Value) {
2804        Self::Map::insert(key, value)
2805    }
2806
2807    /// Remove value at `key`.
2808    #[inline]
2809    fn remove(key: Self::Key) {
2810        Self::Map::remove(key)
2811    }
2812
2813    /// Remove and return value at `key`.
2814    #[inline]
2815    fn take(key: Self::Key) -> Self::Query {
2816        Self::Map::take(key)
2817    }
2818
2819    /// Check if `key` exists in the map.
2820    #[inline]
2821    fn contains_key(key: Self::Key) -> bool {
2822        Self::Map::contains_key(key)
2823    }
2824
2825    /// Mutate value at `key` in-place.
2826    ///
2827    /// Provides `Option<Value>` to handle insert/update/remove semantics.
2828    #[inline]
2829    fn mutate<R>(key: Self::Key, f: impl FnOnce(&mut Option<Self::Value>) -> R) -> R {
2830        Self::Map::mutate_exists(key, f)
2831    }
2832
2833    /// Iterate over all `(key, value)` pairs.
2834    #[inline]
2835    fn iter() -> impl Iterator<Item = (Self::KeyGen, Self::Value)> {
2836        Self::Map::iter()
2837    }
2838
2839    /// Iterate over all keys.
2840    #[inline]
2841    fn iter_keys() -> impl Iterator<Item = Self::KeyGen> {
2842        Self::Map::iter_keys()
2843    }
2844
2845    /// Iterate over all values.
2846    #[inline]
2847    fn iter_values() -> impl Iterator<Item = Self::Value> {
2848        Self::Map::iter_values()
2849    }
2850
2851    /// Drain entire map, yielding all `(key, value)` pairs.
2852    #[inline]
2853    fn drain() -> impl Iterator<Item = (Self::KeyGen, Self::Value)> {
2854        Self::Map::drain()
2855    }
2856
2857    /// Count total number of entries.
2858    #[inline]
2859    fn count() -> usize {
2860        Self::Map::iter_keys().count()
2861    }
2862}