mod r#trait;
mod r#type;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
use better_any::{Tid, TidAble};
use quote::ToTokens;
pub use r#trait::Trait;
pub use r#type::Type;
use proc_macro2::TokenStream;
use crate::maybe_borrowed::MaybeBorrowed;
use super::{context::Context, passed_data::PassedData};
pub trait Generatable<'a, Assert>
where
Self: TidAble<'a>,
Assert: 'a + TidAble<'a>,
{
type GeneratableData: 'a;
type TemplateData: 'a;
const EMITS_NON_CONSTANT_CODE: bool;
fn generatable(context: &mut Context) -> PassedData<Self::GeneratableData>
where
Self: Sized;
fn template(
&self,
context: &mut Context,
passed: &Self::GeneratableData,
) -> PassedData<Self::TemplateData>;
fn assert(
&self,
_context: &mut Context,
_passed: (&Self::GeneratableData, &Self::TemplateData),
_to_assert: &Assert,
) -> Option<TokenStream>;
}
#[derive(Tid)]
#[repr(transparent)]
pub struct StaticTid<T: 'static>(pub T);
impl<T: 'static> From<T> for StaticTid<T> {
fn from(value: T) -> Self {
Self(value)
}
}
impl<'a, T> From<&'a T> for &'a StaticTid<T> {
fn from(value: &'a T) -> Self {
unsafe { &*(value as *const T).cast::<StaticTid<T>>() }
}
}
impl<'a, T> From<&'a mut T> for &'a mut StaticTid<T> {
fn from(value: &'a mut T) -> Self {
unsafe { &mut *(value as *mut T).cast::<StaticTid<T>>() }
}
}
impl<'a, U> From<&'a U> for MaybeBorrowed<'a, StaticTid<U>> {
fn from(value: &'a U) -> Self {
MaybeBorrowed::Borrowed(value.into())
}
}
impl<'a, T> From<T> for MaybeBorrowed<'a, StaticTid<T>> {
fn from(value: T) -> Self {
MaybeBorrowed::Owned(StaticTid(value))
}
}
impl<T: 'static> Deref for StaticTid<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: 'static> DerefMut for StaticTid<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: 'static + ToTokens> ToTokens for StaticTid<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
(**self).to_tokens(tokens);
}
}
impl<T: 'static + PartialEq> PartialEq for StaticTid<T> {
fn eq(&self, other: &Self) -> bool {
(**self).eq(&**other)
}
}
impl<T: 'static + Eq> Eq for StaticTid<T> {}
impl<T: 'static + PartialOrd> PartialOrd for StaticTid<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
(**self).partial_cmp(&**other)
}
}
impl<T: 'static + Ord> Ord for StaticTid<T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
(**self).cmp(&**other)
}
}
impl<T: 'static + Hash> Hash for StaticTid<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}