ref-view 0.1.0

Derive zero-copy reference views for structs and enums
Documentation
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
    )
}