Skip to content

Instantly share code, notes, and snippets.

@0atman
Last active March 25, 2024 14:03
Show Gist options
  • Save 0atman/3e3205d41d99ecbc98bf800861ff0b0c to your computer and use it in GitHub Desktop.
Save 0atman/3e3205d41d99ecbc98bf800861ff0b0c to your computer and use it in GitHub Desktop.
#![allow(dead_code, unused_variables)]
fn main() {}
struct Machine<State> {
data: Vec<u16>,
state: State,
}
struct State1 {}
struct State2 {}
impl Machine<State1> {
fn forward(self) -> Machine<State2> {
let Self { data, state: _ } = self;
Machine {
data,
state: State2 {},
}
}
}
impl Machine<State2> {
fn backward(self) -> Machine<State1> {
Machine {
data: self.data,
state: State1 {},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn good_state() {
let start_state = Machine {
data: [1, 2, 3].into(),
state: State1 {},
};
start_state.forward().backward().forward();
}
#[test]
fn correctly_wont_compile() {
let start_state = Machine {
data: [1, 2, 3].into(),
state: State1 {},
};
start_state.forward().forward();
}
}
fn main() {
let start_state = HttpResponse {
state: Start
};
let headers_state = start_state.status_line(100);
headers_state.response_code();
}
// Primary stuct
struct HttpResponse<State: ResponseState> {
state: State,
}
// States
struct Start;
struct Headers {
response_code: u8,
}
// Trait wiring for Start and Headers,
trait ResponseState {}
impl ResponseState for Start {}
impl ResponseState for Headers {}
// Methods availabe only in the Start state
impl HttpResponse<Start> {
fn status_line(self, response_code: u8)
-> HttpResponse<Headers>
{
HttpResponse {
state: Headers {
response_code,
},
}
}
}
// Methods availabe only in the Headers state
impl HttpResponse<Headers> {
fn response_code(&self) -> u8 {
self.state.response_code
}
}
// Methods availabe in any state - this is not possible without traits!
impl <State: ResponseState> HttpResponse<State> {
#[allow(dead_code)]
fn noop(&self) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment