microrm 0.6.3

Lightweight ORM using sqlite as a backend
Documentation
/// ### Type indirection
///
///
use crate::schema::entity::{Entity, EntityPart, EntityPartList};

/// Trait used to get entity part types by index, used for index schema generation.
pub trait IndexedEntityPart<const N: usize> {
    /// What entity is this part for?
    type Entity: Entity;
    /// The actual target part
    type Part: EntityPart<Entity = Self::Entity>;
}

/// Signifier used to specify which indexed part to retrieve.
pub struct IndexSignifier<const N: usize>;

/// Turns a list of signifiers into an [`EntityPartList`].
pub trait IndexPartList<E: Entity, II> {
    /// The resulting [`EntityPartList`].
    type PartList: EntityPartList<Entity = E>;
}

/// A search index across given fields. Note that since this is a unique index, it also enforces a
/// uniqueness constraint across the fields.
pub type UniqueIndex<E, EPL> = Index<true, E, EPL>;

/// A search index across given fields. Note that since this is not a unique index, it does not
/// enforce any constraints.
pub type SearchIndex<E, EPL> = Index<false, E, EPL>;

/// A search index across given fields that may be unique.
#[doc(hidden)]
pub struct Index<const UNIQUE: bool, E: Entity, EPL: EntityPartList<Entity = E>> {
    _ghost: std::marker::PhantomData<(E, EPL)>,
}

impl<const UNIQUE: bool, E: Entity, EPL: EntityPartList<Entity = E>> Default
    for Index<UNIQUE, E, EPL>
{
    fn default() -> Self {
        Self {
            _ghost: std::marker::PhantomData,
        }
    }
}

impl<const UNIQUE: bool, E: Entity, EPL: EntityPartList<Entity = E>> Clone
    for Index<UNIQUE, E, EPL>
{
    fn clone(&self) -> Self {
        Self {
            _ghost: std::marker::PhantomData,
        }
    }
}

impl<const UNIQUE: bool, E: Entity, EPL: EntityPartList<Entity = E>> super::DatabaseItem
    for Index<UNIQUE, E, EPL>
{
    fn accept_item_visitor(visitor: &mut impl super::DatabaseItemVisitor) {
        visitor.visit_index::<UNIQUE, E, EPL>();
    }

    fn build(_: super::BuildSeal) -> Self
    where
        Self: Sized,
    {
        Self {
            _ghost: std::marker::PhantomData,
        }
    }

    type Subitems = ();
}

macro_rules! entity_index {
    ($($is:ident : $n:tt),+) => {
        impl<E: Entity $( + IndexedEntityPart<$is, Entity = E> )*, $( const $is: usize ),*> IndexPartList<E, ( $( IndexSignifier<$is> ),*, )> for E {
            #[allow(unused_parens)]
            type PartList = ( $( <E as IndexedEntityPart<$is>>::Part ),* );
        }
    }
}

entity_index!(N0:0);
entity_index!(N0:0, N1:1);
entity_index!(N0:0, N1:1, N2:2);
entity_index!(N0:0, N1:1, N2:2, N3:3);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9, N10:10);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9, N10:10, N11:11);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9, N10:10, N11:11, N12:12);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9, N10:10, N11:11, N12:12, N13:13);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9, N10:10, N11:11, N12:12, N13:13, N14:14);
entity_index!(N0:0, N1:1, N2:2, N3:3, N4:4, N5:5, N6:6, N7:7, N8:8, N9:9, N10:10, N11:11, N12:12, N13:13, N14:14, N15:15);