/*
    Appellation: driver <module>
    Contrib: @FL03
*/

/// A basic trait denoting objects that can be used to hold other entities
pub trait RawStore {
    type Elem;

    private!();
}

/// A trait that extends the `RawStore` with various creation routines, accessors, etc.
pub trait Store: RawStore
where
    Self: FromIterator<Self::Elem>,
{
    private!();
}

pub trait SeqStore: Store
where
    Self: core::ops::Index<Self::Idx>,
{
    type Idx;

    private!();
}

/// This trait is used define the symbols available to the engines
pub trait Alphabet: RawStore {
    private!();
}

/*
 ************* Implementations *************
*/
impl<T, const N: usize> Alphabet for [T; N] {
    seal!();
}

impl<T> Alphabet for Vec<T> {
    seal!();
}

impl<S, T> Store for S
where
    S: FromIterator<T> + RawStore<Elem = T>,
{
    seal!();
}
macro_rules! impl_store {
    (@impl $($u:ident)::*) => {
        impl<T> RawStore for $($u)::*<T> {
            type Elem = T;

            seal!();
        }
    };
    ($($($u:ident)::*),* $(,)?) => {
        $(
            impl_store!(@impl $($u)::*);
        )*
    };
}

impl<U> RawStore for [U] {
    type Elem = U;

    seal!();
}

impl<T, const N: usize> RawStore for [T; N] {
    type Elem = T;

    seal!();
}

impl_store! {
    std::cell::Cell,
    std::cell::RefCell,
    std::sync::Arc,
    std::sync::Mutex,
    std::sync::RwLock,
    std::vec::Vec
}
