Created
June 29, 2024 10:43
-
-
Save phunguyen19/d952b9d5de13b85e7f85591758ea72d2 to your computer and use it in GitHub Desktop.
Rust Type-State pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait FileState {} | |
// We need this to define | |
// `close` method for multiple states | |
trait Closable { | |
fn close(self) -> File<ClosedFile>; | |
} | |
struct File<S: FileState> { | |
state: S, | |
} | |
struct InitialFile {} | |
impl FileState for InitialFile {} | |
struct OpenedFile {} | |
impl FileState for OpenedFile {} | |
struct ClosedFile {} | |
impl FileState for ClosedFile {} | |
struct ReadingFile {} | |
impl FileState for ReadingFile {} | |
impl File<InitialFile> { | |
fn new() -> Self { | |
println!("Creating new file"); | |
File::<InitialFile> { | |
state: InitialFile {}, | |
} | |
} | |
fn open(self) -> File<OpenedFile> { | |
println!("Opening file"); | |
File::<OpenedFile> { | |
state: OpenedFile {}, | |
} | |
} | |
} | |
impl Closable for File<OpenedFile> { | |
fn close(self) -> File<ClosedFile> { | |
println!("Closing file"); | |
File::<ClosedFile> { | |
state: ClosedFile {}, | |
} | |
} | |
} | |
impl File<OpenedFile> { | |
fn read(self) -> File<ReadingFile> { | |
println!("Reading file"); | |
File::<ReadingFile> { | |
state: ReadingFile {}, | |
} | |
} | |
} | |
impl Closable for File<ReadingFile> { | |
fn close(self) -> File<ClosedFile> { | |
println!("Closing file"); | |
File::<ClosedFile> { | |
state: ClosedFile {}, | |
} | |
} | |
} | |
impl File<ClosedFile> { | |
fn is_closed(self) -> bool { | |
true | |
} | |
} | |
fn main() { | |
let file = File::<InitialFile>::new(); | |
let file = file.open(); | |
let file = file.read(); | |
let file = file.close(); | |
let is_closed = file.is_closed(); | |
println!("Is closed: {}", is_closed); | |
// Compiling error checking | |
let file = File::<InitialFile>::new(); | |
let file = file.open(); | |
let file = file.close(); | |
let file = file.read(); // error on compile time | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment