use core::fmt::Debug;
use core::marker::PhantomData;
use crate::ctor::Ctor;
use crate::err::Error;
use crate::regex::Regex;
use crate::regex::impl_not_for_regex;
use crate::span::Span;
#[cfg(feature = "alloc")]
use crate::alloc;
pub struct Adapter<C, I> {
inner: I,
marker: PhantomData<C>,
}
impl_not_for_regex!(Adapter<C, I>);
impl<I: Debug, C> Debug for Adapter<C, I> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Adapter")
.field("inner", &self.inner)
.finish()
}
}
impl<I: Default, C> Default for Adapter<C, I> {
fn default() -> Self {
Self {
inner: Default::default(),
marker: Default::default(),
}
}
}
impl<I: Clone, C> Clone for Adapter<C, I> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
marker: PhantomData,
}
}
}
impl<I: Copy, C> Copy for Adapter<C, I> {}
impl<C, I> From<I> for Adapter<C, I> {
fn from(value: I) -> Self {
Self {
inner: value,
marker: PhantomData,
}
}
}
impl<C, I> Adapter<C, I> {
pub const fn new(inner: I) -> Self {
Self {
inner,
marker: PhantomData,
}
}
pub fn with_inner(mut self, inner: I) -> Self {
self.inner = inner;
self
}
pub fn inner(&self) -> &I {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut I {
&mut self.inner
}
pub fn set_inner(&mut self, inner: I) -> &mut Self {
self.inner = inner;
self
}
pub fn into_inner(self) -> I {
self.inner
}
}
#[derive(Debug)]
pub struct CtorOnlyFunAdapter<C, F, O, H> {
inner: F,
marker: core::marker::PhantomData<(C, O, H)>,
}
impl<C, F, O, H> Clone for CtorOnlyFunAdapter<C, F, O, H>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
marker: self.marker,
}
}
}
impl<C, F, O, H> Copy for CtorOnlyFunAdapter<C, F, O, H> where F: Copy {}
impl<C, F: Default, O, H> Default for CtorOnlyFunAdapter<C, F, O, H> {
fn default() -> Self {
Self {
inner: Default::default(),
marker: Default::default(),
}
}
}
impl<C, F, O, H> CtorOnlyFunAdapter<C, F, O, H>
where
F: Fn(&mut C, &mut H) -> Result<O, Error>,
{
pub const fn new(inner: F) -> Self {
Self {
inner,
marker: core::marker::PhantomData,
}
}
}
impl<C, O, F, H> Regex<C> for CtorOnlyFunAdapter<C, F, O, H>
where
F: Fn(&mut C, &mut H) -> Result<O, Error>,
{
fn try_parse(&self, _: &mut C) -> Result<Span, Error> {
unimplemented!("FunAdapter not support Regex trait")
}
}
impl<C, O, F, H> Ctor<C, O, H> for CtorOnlyFunAdapter<C, F, O, H>
where
F: Fn(&mut C, &mut H) -> Result<O, Error>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, handler: &mut H) -> Result<O, Error> {
(self.inner)(ctx, handler)
}
}
impl<C, O, H, F> Adapter<C, CtorOnlyFunAdapter<C, F, O, H>>
where
F: Fn(&mut C, &mut H) -> Result<O, Error>,
{
pub fn func(func: F) -> Self {
Self::new(CtorOnlyFunAdapter::new(func))
}
}
#[cfg(feature = "alloc")]
impl<T, C> Adapter<C, BoxAdapter<C, T>> {
pub fn r#box(ctor: T) -> Self {
Self::new(BoxAdapter::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<T, C> Adapter<C, alloc::Rc<T>> {
pub fn rc(ctor: T) -> Self {
Self::new(alloc::Rc::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<T, C> Adapter<C, alloc::Arc<T>> {
pub fn arc(ctor: T) -> Self {
Self::new(alloc::Arc::new(ctor))
}
}
impl<T, C> Adapter<C, core::cell::Cell<T>> {
pub fn cell(ctor: T) -> Self {
Self::new(core::cell::Cell::new(ctor))
}
}
#[cfg(feature = "std")]
impl<T, C> Adapter<C, crate::std::Mutex<T>> {
pub fn mutex(ctor: T) -> Self {
Self::new(crate::std::Mutex::new(ctor))
}
}
impl<C, T> Adapter<C, core::cell::RefCell<T>> {
pub fn refcell(ctor: T) -> Self {
Self::new(core::cell::RefCell::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Box<dyn Ctor<C, O, H> + 'b>> {
pub fn dyn_box(ctor: impl Ctor<C, O, H> + 'b) -> Self {
Self::new(alloc::Box::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Box<dyn Ctor<C, O, H> + Send + 'b>> {
pub fn dyn_box_send(ctor: impl Ctor<C, O, H> + Send + 'b) -> Self {
Self::new(alloc::Box::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Box<dyn Ctor<C, O, H> + Send + Sync + 'b>> {
pub fn dyn_box_sync(ctor: impl Ctor<C, O, H> + Send + Sync + 'b) -> Self {
Self::new(alloc::Box::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Arc<dyn Ctor<C, O, H> + 'b>> {
pub fn dyn_arc(ctor: impl Ctor<C, O, H> + 'b) -> Self {
Self::new(alloc::Arc::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Arc<dyn Ctor<C, O, H> + Send + 'b>> {
pub fn dyn_arc_send(ctor: impl Ctor<C, O, H> + Send + 'b) -> Self {
Self::new(alloc::Arc::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Arc<dyn Ctor<C, O, H> + Send + Sync + 'b>> {
pub fn dyn_arc_sync(ctor: impl Ctor<C, O, H> + Send + Sync + 'b) -> Self {
Self::new(alloc::Arc::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Rc<dyn Ctor<C, O, H> + 'b>> {
pub fn dyn_rc(ctor: impl Ctor<C, O, H> + 'b) -> Self {
Self::new(alloc::Rc::new(ctor))
}
}
#[cfg(feature = "alloc")]
impl<'b, C, O, H> Adapter<C, alloc::Rc<dyn Ctor<C, O, H> + Send + 'b>> {
pub fn dyn_rc_send(ctor: impl Ctor<C, O, H> + Send + 'b) -> Self {
Self::new(alloc::Rc::new(ctor))
}
}
impl<C, I> Regex<C> for Adapter<C, I>
where
I: Regex<C>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
self.inner.try_parse(ctx)
}
}
impl<C, O, H, I> Ctor<C, O, H> for Adapter<C, I>
where
I: Ctor<C, O, H>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, handler: &mut H) -> Result<O, Error> {
Ctor::construct(&self.inner, ctx, handler)
}
}
pub struct DynRefAdapter<'b, C, O, H> {
inner: &'b dyn Ctor<C, O, H>,
}
impl<'b, C, O, H> Clone for DynRefAdapter<'b, C, O, H> {
fn clone(&self) -> Self {
*self
}
}
impl<'b, C, O, H> Copy for DynRefAdapter<'b, C, O, H> {}
impl<'b, C, O, H> DynRefAdapter<'b, C, O, H> {
pub const fn new<T: Ctor<C, O, H>>(inner: &'b T) -> Self {
Self { inner }
}
}
impl<'b, C, O, H> Regex<C> for DynRefAdapter<'b, C, O, H> {
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
Regex::try_parse(self.inner, ctx)
}
}
impl<'b, C, O, H> Ctor<C, O, H> for DynRefAdapter<'b, C, O, H> {
fn construct(&self, ctx: &mut C, handler: &mut H) -> Result<O, Error> {
Ctor::construct(self.inner, ctx, handler)
}
}
#[cfg(feature = "alloc")]
mod box_adapter {
use crate::ctor::Ctor;
use crate::err::Error;
use crate::regex::Regex;
use crate::span::Span;
#[derive(Debug)]
pub struct BoxAdapter<C, I> {
inner: crate::alloc::Box<I>,
marker: core::marker::PhantomData<C>,
}
impl<C, I> Clone for BoxAdapter<C, I>
where
I: Clone,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
marker: self.marker,
}
}
}
impl<I: Default, C> Default for BoxAdapter<C, I> {
fn default() -> Self {
Self {
inner: Default::default(),
marker: Default::default(),
}
}
}
impl<C, I> BoxAdapter<C, I> {
pub fn new(inner: I) -> Self {
Self {
inner: crate::alloc::Box::new(inner),
marker: core::marker::PhantomData,
}
}
}
impl<C, I> Regex<C> for BoxAdapter<C, I>
where
I: Regex<C>,
{
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
self.inner.try_parse(ctx)
}
}
impl<C, O, I, H> Ctor<C, O, H> for BoxAdapter<C, I>
where
I: Ctor<C, O, H>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, handler: &mut H) -> Result<O, Error> {
Ctor::construct(self.inner.as_ref(), ctx, handler)
}
}
}
#[cfg(feature = "alloc")]
pub use box_adapter::*;