use optics::{HasGetter, HasSetter, mapped_fallible_iso, mapped_lens, mapped_prism};
#[allow(dead_code)]
#[derive(Debug, Clone)]
struct HttpConfig {
bind_address: Option<String>,
workers: usize,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
struct AppConfig {
http: HttpConfig,
name: String,
}
fn main() {
let http_lens = mapped_lens(
|app: &AppConfig| app.http.clone(),
|app, http| app.http = http,
);
let bind_address_prism = mapped_prism(
|http: &HttpConfig| http.bind_address.clone().ok_or(()),
|http, addr| http.bind_address = Some(addr),
);
let minimum_port = 1024;
let port_fallible_iso = mapped_fallible_iso(
|addr: &String| {
addr.rsplit(':')
.next()
.and_then(|port| port.parse::<u16>().ok())
.ok_or(())
},
move |port: &u16| {
(*port > minimum_port)
.then_some(format!("0.0.0.0:{}", port))
.ok_or(())
},
);
let http_bind_address_prism = http_lens.compose_with_prism(bind_address_prism);
let http_bind_address_port_prism =
http_bind_address_prism.compose_with_fallible_iso::<(), _, _>(port_fallible_iso);
let mut config = AppConfig {
http: HttpConfig {
bind_address: Some("127.0.0.1:8080".to_string()),
workers: 4,
},
name: "my_app".into(),
};
let port = http_bind_address_port_prism.try_get(&config).unwrap();
println!("Current port: {}", port);
http_bind_address_port_prism.set(&mut config, port + 1);
println!("Updated config: {:?}", config);
}