Skip to content

Instantly share code, notes, and snippets.

@alepez
Last active April 3, 2023 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alepez/6dd05d1df6fbb2b8d369ba6401acb442 to your computer and use it in GitHub Desktop.
Save alepez/6dd05d1df6fbb2b8d369ba6401acb442 to your computer and use it in GitHub Desktop.
// 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