mod example {
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use state_shift::{impl_state, type_state};
pub struct MyParentObject<'base> {
#[allow(unused)]
inner: MaybeUninit<*mut core::ffi::c_void>,
_marker: PhantomData<&'base ()>,
}
impl<'base> MyParentObject<'base> {
pub fn new() -> Self {
MyParentObject {
inner: MaybeUninit::zeroed(),
_marker: PhantomData,
}
}
pub fn method(&'base self) -> MethodBuilder {
MethodBuilder::new()
}
}
pub struct Method {}
impl Method {
pub fn start(self) -> Result<(), String> {
Ok(())
}
}
#[type_state(states = (Unset, ASet, BSet, AOrBSet), slots = (Unset, Unset, Unset))]
pub struct MethodBuilder {
#[allow(unused)]
slot_a: Option<u8>,
slot_b: Option<u8>,
}
impl MethodBuilder {}
#[impl_state]
impl MethodBuilder {
#[require(Unset, Unset, Unset)] pub fn new() -> MethodBuilder {
MethodBuilder {
slot_a: None,
slot_b: None,
}
}
#[require(Unset, B, C)]
#[switch_to(ASet, B, AOrBSet)]
pub fn set_slot_a(self, slot_a: u8) -> MethodBuilder {
MethodBuilder {
slot_a: Some(slot_a),
slot_b: self.slot_b,
}
}
#[require(A, BSet, C)]
#[switch_to(A, BSet, AOrBSet)]
pub fn set_slot_b(self, slot_b: u8) -> MethodBuilder {
MethodBuilder {
slot_a: self.slot_a,
slot_b: Some(slot_b),
}
}
#[require(A, B, AOrBSet)]
pub fn build(self) -> Method {
Method {}
}
#[require(A, B, AOrBSet)]
pub fn start(self) -> Result<(), String> {
Ok(())
}
}
}
#[test]
fn test_method_builder() {
let myparentobj = example::MyParentObject::new();
let meth = myparentobj.method().set_slot_a(42).build();
let res = meth.start();
assert!(res.is_ok())
}