#![no_std]
#![allow(clippy::collapsible_if)]
mod dynamic;
mod into;
mod item;
mod r#macro;
mod query;
#[doc(hidden)]
pub use core::any::Any;
pub use dynamic::*;
pub use into::IntoMetaTuple;
pub use item::MetaItem;
pub use query::MetaQuery;
#[doc(hidden)]
pub use query::MetaQuerySingle;
#[cfg(feature = "derive")]
pub use meta_tuple_derive::{MetaItem, MetaQuery, MetaTuple};
#[doc(hidden)]
pub use polonius_the_crab::{polonius_loop, polonius_return};
pub unsafe trait MetaTuple: MetaAny {
fn get<T: 'static>(&self) -> Option<&T>;
fn get_mut<T: 'static>(&mut self) -> Option<&mut T>;
fn get_mut_ptr<T: 'static>(&self) -> Option<*mut T>;
fn join<T: 'static>(self, other: T) -> Join<Self, MetaItem<T>>
where
Self: Sized,
{
Join(self, MetaItem(other))
}
fn join_ref<T: 'static>(self, other: &T) -> Join<Self, &MetaItem<T>>
where
Self: Sized,
{
Join(self, MetaItem::from_ref(other))
}
fn join_mut<T: 'static>(self, other: &mut T) -> Join<Self, &mut MetaItem<T>>
where
Self: Sized,
{
Join(self, MetaItem::from_mut(other))
}
fn join_tuple<T: MetaTuple>(self, other: T) -> Join<Self, T>
where
Self: Sized,
{
Join(self, other)
}
fn join_dyn_ref(self, other: &dyn MetaAny) -> Join<Self, &DynMetaTuple>
where
Self: Sized,
{
Join(self, DynMetaTuple::from_ref(other))
}
fn join_dyn_mut(self, other: &mut dyn MetaAny) -> Join<Self, &mut DynMetaTuple>
where
Self: Sized,
{
Join(self, DynMetaTuple::from_mut(other))
}
fn query_ref<T: MetaQuery>(&self) -> Option<T::Output<'_>> {
T::query_ref(self)
}
fn query_mut<T: MetaQuery>(&mut self) -> Option<T::Output<'_>> {
T::query_mut(self)
}
}
unsafe impl<T: MetaTuple + ?Sized> MetaTuple for &T {
fn get<U: 'static>(&self) -> Option<&U> {
MetaTuple::get(*self)
}
fn get_mut<U: 'static>(&mut self) -> Option<&mut U> {
None
}
fn get_mut_ptr<U: 'static>(&self) -> Option<*mut U> {
None
}
}
unsafe impl<T: MetaTuple + ?Sized> MetaTuple for &mut T {
fn get<U: 'static>(&self) -> Option<&U> {
MetaTuple::get(*self)
}
fn get_mut<U: 'static>(&mut self) -> Option<&mut U> {
MetaTuple::get_mut(*self)
}
fn get_mut_ptr<U: 'static>(&self) -> Option<*mut U> {
MetaTuple::get_mut_ptr(*self)
}
}
unsafe impl MetaTuple for () {
fn get<T: 'static>(&self) -> Option<&T> {
None
}
fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
None
}
fn get_mut_ptr<T: 'static>(&self) -> Option<*mut T> {
None
}
}
unsafe impl<T: 'static> MetaTuple for MetaItem<T> {
fn get<U: 'static>(&self) -> Option<&U> {
(&self.0 as &dyn Any).downcast_ref()
}
fn get_mut<U: 'static>(&mut self) -> Option<&mut U> {
(&mut self.0 as &mut dyn Any).downcast_mut()
}
fn get_mut_ptr<U: 'static>(&self) -> Option<*mut U> {
(&self.0 as &dyn Any)
.downcast_ref()
.map(|x| x as *const U as *mut U)
}
}
unsafe impl<T: 'static> MetaTuple for Option<T> {
fn get<U: 'static>(&self) -> Option<&U> {
if let Some(v) = self.as_ref() {
if let Some(result) = (v as &dyn Any).downcast_ref() {
return Some(result);
}
}
None
}
fn get_mut<U: 'static>(&mut self) -> Option<&mut U> {
if let Some(v) = self.as_mut() {
if let Some(result) = (v as &mut dyn Any).downcast_mut() {
return Some(result);
}
}
None
}
fn get_mut_ptr<U: 'static>(&self) -> Option<*mut U> {
if let Some(v) = self.as_ref() {
if let Some(result) = (v as &dyn Any).downcast_ref() {
return Some(result as *const U as *mut U);
}
}
None
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Join<A, B>(pub A, pub B);
unsafe impl<A: MetaTuple, B: MetaTuple> MetaTuple for Join<A, B> {
fn get<T: 'static>(&self) -> Option<&T> {
self.0.get().or_else(|| self.1.get())
}
fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
self.0.get_mut().or_else(|| self.1.get_mut())
}
fn get_mut_ptr<T: 'static>(&self) -> Option<*mut T> {
self.0.get_mut_ptr().or_else(|| self.1.get_mut_ptr())
}
}