Skip to content

Instantly share code, notes, and snippets.

@alienscience
Created January 20, 2019 10:21
Show Gist options
  • Save alienscience/94ff5809c5822bec4936edc0d8da6141 to your computer and use it in GitHub Desktop.
Save alienscience/94ff5809c5822bec4936edc0d8da6141 to your computer and use it in GitHub Desktop.
Go like builder functions in Rust
trait Builder {
type Config : Default;
fn build(v: &[BuilderFn<Self::Config>]) -> Self::Config {
let mut ret = Default::default();
for c in v {
c(&mut ret)
}
ret
}
}
type BuilderFn<T> = Box<dyn Fn(&mut T) -> ()>;
//----------------------------------
#[derive(Debug)]
struct Server {
host: String,
target: String,
port: i32,
timeout: i32,
}
impl Default for Server {
fn default() -> Self {
Self {
host: "0.0.0.0".to_string(),
target: "8.8.8.8".to_string(),
port: 0,
timeout: 1000,
}
}
}
impl Builder for Server {
type Config = Self;
}
fn host<S>(s: S) -> BuilderFn<Server>
where
S: Into<String>,
{
let host = s.into();
Box::new(move |config: &mut Server| config.host = host.clone())
}
fn target<S>(s: S) -> BuilderFn<Server>
where
S: Into<String>,
{
let target = s.into();
Box::new(move |config: &mut Server| config.target = target.clone())
}
fn port(n: i32) -> BuilderFn<Server> {
Box::new(move |config: &mut Server| config.port = n)
}
fn timeout(n: i32) -> BuilderFn<Server> {
Box::new(move |config: &mut Server| config.timeout = n)
}
fn main() {
let server = Server::build(&[
port(25),
host("localhost"),
target("example.com"),
timeout(2000),
]);
println!("server = {:?}", server);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment