nonymous 0.7.0

DNS protocol and algorithm library
Documentation
#![allow(dead_code)]

use core::convert::Infallible;
use core::marker::PhantomData;

use super::{Buffer, Builder, ChildBuilder, PushBuilder, Sink};

impl<'b, P: Builder<'b>> ChildBuilder<'b, P> for Child<'b, P, ChildStep0> {
    fn parent(&mut self) -> &mut P {
        &mut self.parent
    }
}
impl<'b, P: Builder<'b>> PushBuilder<'b, P> for Child<'b, P, ChildStep0> {
    type Error = Infallible;
    fn push(parent: P) -> Result<Self, Self::Error> {
        Ok(Self {
            buffer: PhantomData,
            parent,
            step: ChildStep0,
        })
    }
}
struct FooBuilder<'b, P: Builder<'b>, Q> {
    buffer: PhantomData<&'b mut dyn Buffer>,
    parent: P,
    step: Q,
}
impl<'b, P: Builder<'b>> TryFrom<FooBuilder<'b, P, FooBaz>> for FooBuilder<'b, P, FooQux> {
    type Error = FooError;
    fn try_from(value: FooBuilder<'b, P, FooBaz>) -> Result<Self, Self::Error> {
        Ok(Self {
            buffer: value.buffer,
            parent: value.parent,
            step: FooQux,
        })
    }
}
struct FooBar;
struct FooBaz;
struct FooQux;
#[derive(Debug)]
enum FooError {
    Child(Infallible),
}
transition! { FooBuilder.step { (buffer, parent) FooBar -> FooBaz; } }
struct Parent<'b, P: Builder<'b>, Q> {
    buffer: PhantomData<&'b mut dyn Buffer>,
    parent: P,
    step: Q,
}
struct ParentStep0;
struct ParentStep1;
struct ParentStep2;
trait SpecialSteps {}
impl SpecialSteps for ParentStep0 {}
impl SpecialSteps for ParentStep1 {}
trait OtherStates {}
impl SpecialSteps for ParentStep2 {}
struct Child<'b, P: Builder<'b>, Q> {
    buffer: PhantomData<&'b mut dyn Buffer>,
    parent: P,
    step: Q,
}
struct ChildStep0;
builder! {
    <'b, P> FooBuilder {
        Builder [Q];
        @ <P> Q [Q]:
            /// a
            fn handle_tu[T, U: Ord](mut self, t: T, u: U) -> Self = { drop((t, u)); self }
        @ <Parent<'b, P, Q>> FooBar [Q: SpecialSteps]:
            pub fn into_baz(mut self) = [into FooBaz] { self }
        @ <P> FooBaz:
            pub fn try_into_qux(mut self) = [try_into FooQux | FooError] { self }
        @ <P> FooQux:
            pub fn push_child[T, U: Ord](mut self, t: T, u: U) =
                [push Child<ChildStep0> | FooError::Child]
                { self.handle_tu(t, u) }
    }
}
builder! { <'b, P> Parent { Builder [Q]; } }
builder! { <'b, P> Child { Builder [Q]; } }

#[test]
fn test() -> Result<(), FooError> {
    let mut buffer = arrayvec::ArrayVec::<u8, 4096>::new();
    let parent: Sink = (&mut buffer).try_into().unwrap();
    let parent = Parent {
        buffer: PhantomData,
        parent,
        step: ParentStep0,
    };
    let foo = FooBuilder {
        buffer: PhantomData,
        parent,
        step: FooBar,
    };

    foo.into_baz().try_into_qux()?.push_child(false, 0)?;

    Ok(())
}