typestate-rs
typestate-rs copied to clipboard
Default implementations don't work
Given the following:
use typestate::typestate;
#[typestate]
mod my_state {
#[automaton]
pub struct Automaton;
#[state]
pub struct State1(bool);
pub trait State1: Sized {
fn new() -> State1 {
Automaton {
state: State1(true),
}
}
fn to_state_2(mut self) -> State2 {
Automaton {
state: State2(true),
}
}
}
#[state]
pub struct State2(bool);
pub trait State2: Sized {
fn done(self) {}
}
}
fn t() {
use my_state::*;
let s1 = Automaton::new();
}
We get an error stating that State1State
trait is in scope, but not implemented for Automaton<State1>
.
If I instead implement the traits, all is well:
#[automaton]
pub struct Automaton;
#[state]
pub struct State1;
pub trait State1 {
fn new() -> State1;
fn to_state_2(self) -> State2;
}
impl State1State for Automaton<State1> {
fn new() -> Automaton<State1> {
Automaton { state: State1 }
}
fn to_state_2(self) -> Automaton<State2> {
Automaton { state: State2 }
}
}
#[state]
pub struct State2;
pub trait State2 {
fn done(self);
}
impl State2State for Automaton<State2> {
fn done(self) {}
}
}
fn t() {
use my_state::*;
let s1 = Automaton::new();
}
Could you run cargo expand
on your example?
https://github.com/dtolnay/cargo-expand
Sure, he is the cargo-expand output:
mod _t {
use typestate::typestate;
///```mermaid
///stateDiagram-v2
///[*] --> State1 : new
///State1 --> State2 : to_state_2
///State2 --> [*] : done
///```
mod my_state {
pub struct Automaton<State: AutomatonState> {
pub state: State,
}
pub struct State1(bool);
pub trait State1State: Sized {
fn new() -> Automaton<State1> {
Automaton {
state: State1(true),
}
}
#[must_use]
fn to_state_2(mut self) -> Automaton<State2> {
Automaton {
state: State2(true),
}
}
}
pub struct State2(bool);
pub trait State2State: Sized {
fn done(self) {}
}
#[doc(hidden)]
mod __private {
pub trait AutomatonState {}
}
pub trait AutomatonState: __private::AutomatonState {}
impl<__T: ?::core::marker::Sized> AutomatonState for __T where __T: __private::AutomatonState {}
impl __private::AutomatonState for State1 {}
impl __private::AutomatonState for State2 {}
}
fn t() {
use my_state::*;
}
}