144 lines
3.1 KiB
Org Mode
144 lines
3.1 KiB
Org Mode
* effers
|
|
effect handlers in rust
|
|
|
|
** how to use
|
|
*** defining effects
|
|
effects are defined with traits
|
|
|
|
#+begin_src rust
|
|
trait Printer {
|
|
fn print(&mut self, s: &str);
|
|
}
|
|
trait Logger {
|
|
fn debug(&mut self, s: &str);
|
|
fn info(&mut self, s: &str);
|
|
}
|
|
#+end_src
|
|
|
|
all the trait functions (that are used in programs) must take ~&mut self~ as a parameter
|
|
|
|
*** defining a program
|
|
|
|
programs are defined as a normal function, with the added ~program~ attribute
|
|
|
|
#+begin_src rust
|
|
#[program(Smth => Printer(print as p), Logger(debug, info))]
|
|
fn smth(val: u8) -> u8 {
|
|
p("hey hi hello");
|
|
|
|
debug("this is a debug-level log");
|
|
info("this is a info-level log");
|
|
|
|
val + 3
|
|
}
|
|
#+end_src
|
|
|
|
the first token (~Smth~) will be the name of the program. effects are listed after the ~=>~ token
|
|
|
|
**** listing effects
|
|
effects are listed by writing the trait's name, followed by a parenthesized list of the functions that will be used
|
|
|
|
functions can be given an alias using the ~as~ keyword
|
|
|
|
*** defining effect handlers
|
|
effect handlers are defined by declaring a struct, and implementing the trait on it
|
|
|
|
#+begin_src rust
|
|
struct IoPrinter;
|
|
impl Printer for IoPrinter {
|
|
fn print(&mut self, s: &str) {
|
|
println!("{}", s)
|
|
}
|
|
}
|
|
|
|
struct FileLogger;
|
|
impl Logger for FileLogger {
|
|
fn debug(&mut self, s: &str) {
|
|
println!("debug: {}", s)
|
|
}
|
|
fn info(&mut self, s: &str) {
|
|
println!("info: {}", s)
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** running programs
|
|
programs are run by providing the corresponding handlers in order, and finally calling the ~run~ method, providing it the required parameters
|
|
|
|
#+begin_src rust
|
|
let result: u8 = Smth.add(IoPrinter).add(FileLogger).run(3);
|
|
assert_eq!(result, 6);
|
|
#+end_src
|
|
|
|
** full example
|
|
#+begin_src rust
|
|
use effers::program;
|
|
|
|
#[program(Smth => Printer(print as p), Logger(debug, info))]
|
|
fn smth(val: u8) -> u8 {
|
|
p("hey hi hello");
|
|
|
|
debug("this is a debug-level log");
|
|
info("this is a info-level log");
|
|
|
|
val + 3
|
|
}
|
|
|
|
fn main() {
|
|
// maybe smth like this?
|
|
let result: u8 = Smth.add(IoPrinter).add(FileLogger).run(3);
|
|
assert_eq!(result, 6);
|
|
let other_result: u8 = Smth
|
|
.add(IoPrinter)
|
|
.add(NetworkLogger {
|
|
credentials: "secret password".to_string(),
|
|
})
|
|
.run(8);
|
|
assert_eq!(other_result, 11);
|
|
}
|
|
|
|
// effects
|
|
trait Printer {
|
|
fn print(&mut self, s: &str);
|
|
}
|
|
trait Logger {
|
|
fn debug(&mut self, s: &str);
|
|
fn info(&mut self, s: &str);
|
|
}
|
|
|
|
struct IoPrinter;
|
|
impl Printer for IoPrinter {
|
|
fn print(&mut self, s: &str) {
|
|
println!("{}", s)
|
|
}
|
|
}
|
|
|
|
struct FileLogger;
|
|
impl Logger for FileLogger {
|
|
fn debug(&mut self, s: &str) {
|
|
println!("debug: {}", s)
|
|
}
|
|
fn info(&mut self, s: &str) {
|
|
println!("info: {}", s)
|
|
}
|
|
}
|
|
|
|
struct NetworkLogger {
|
|
credentials: String,
|
|
}
|
|
impl Logger for NetworkLogger {
|
|
fn debug(&mut self, s: &str) {
|
|
println!(
|
|
"debug through network: {}; with password {}",
|
|
s, self.credentials
|
|
)
|
|
}
|
|
fn info(&mut self, s: &str) {
|
|
println!(
|
|
"info through network: {}; with password {}",
|
|
s, self.credentials
|
|
)
|
|
}
|
|
}
|
|
#+end_src
|