use ref_view::RefView;
#[derive(RefView)]
#[ref_view(name = UserPublicView, omit(email, api_token))]
struct User {
id: u64,
name: String,
email: Option<String>,
api_token: String,
}
fn render_user<V: UserView>(user: &V) -> String {
let email = user.email().map(String::as_str).unwrap_or("<hidden>");
let token = user.api_token().map(String::as_str).unwrap_or("<hidden>");
format!(
"id={} name={} email={} token={}",
user.id(),
user.name(),
email,
token
)
}
fn main() {
let user = User {
id: 42,
name: "Ada".to_string(),
email: Some("ada@example.com".to_string()),
api_token: "secret-token".to_string(),
};
let full = UserRef::from(&user);
let public = UserPublicView::from(&user);
println!("{}", render_user(&full));
println!("{}", render_user(&public));
let config = Config {
endpoint: "https://example.test".to_string(),
timeout_ms: 5000,
secret: Some("token".to_string()),
};
println!("{}", connection_label(&config));
println!("{}", connection_label(&ConfigRef::from(&config)));
println!("{}", connection_label(&ConfigWithoutSecret::from(&config)));
}
#[derive(RefView)]
#[ref_view(trait_name = ConfigLike)]
#[ref_view(name = ConfigWithoutSecret, omit(secret))]
struct Config {
endpoint: String,
timeout_ms: u64,
secret: Option<String>,
}
fn connection_label<C: ConfigLike>(config: &C) -> String {
let secret_state = if config.secret().is_some() {
"with-secret"
} else {
"without-secret"
};
format!(
"{} timeout={}ms {}",
config.endpoint(),
config.timeout_ms(),
secret_state
)
}