Last active
April 3, 2023 10:12
-
-
Save alepez/6dd05d1df6fbb2b8d369ba6401acb442 to your computer and use it in GitHub Desktop.
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
// You have an API which requires functions to be called in a defined order | |
// This may be a C API | |
mod no_order_constraint { | |
pub fn one() { | |
println!("one"); | |
} | |
pub fn two() { | |
println!("two"); | |
} | |
} | |
// You can wrap the unsafe API in a safer one, which prevent calling two() | |
// before one() is called. | |
mod order_constraint { | |
use super::no_order_constraint as noc; | |
// This structure is private to this module, so no one can create an instance | |
// of A and B outside this module. | |
struct Priv; | |
// These structs are public, because they are "leaked" from the module | |
// But an instance of them cannot be created anywhere, because Priv is private. | |
pub struct A(Priv); | |
pub struct B(Priv); | |
// When you have an A, you can only call one() and get a B | |
impl A { | |
pub fn one(self) -> B { | |
noc::one(); | |
B(Priv) | |
} | |
} | |
// When you have a B, you can only call two() | |
impl B { | |
pub fn two(self) { | |
noc::two(); | |
} | |
} | |
// This is the only function able to create instance of A | |
pub fn start() -> A { | |
A(Priv) | |
} | |
} | |
fn main() { | |
{ | |
use no_order_constraint::*; | |
// You can call them in the wrong order | |
two(); | |
one(); | |
} | |
println!("---"); | |
{ | |
use order_constraint::*; | |
// You cannot call them in the wrong order, it is forbidden by types | |
let x = start(); | |
let x = x.one(); | |
x.two(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment