#![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]:
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(())
}