config-easy 0.2.1

A small interactive settings menu for command-line Rust applications
Documentation
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let connection = rusqlite::Connection::open_in_memory()?;

    connection.execute(
        "CREATE TABLE app_config (
            name TEXT PRIMARY KEY,
            setting TEXT NOT NULL,
            display_order INTEGER NOT NULL
        )",
        [],
    )?;
    connection.execute(
        "CREATE TABLE sync_state (key TEXT PRIMARY KEY, value TEXT NOT NULL)",
        [],
    )?;
    connection.execute(
        "INSERT INTO app_config (name, setting, display_order)
         VALUES (?1, ?2, ?3), (?4, ?5, ?6)",
        rusqlite::params!["log_level", "info", 1, "api_token", "secret-token", 2],
    )?;
    connection.execute(
        "INSERT INTO sync_state (key, value) VALUES ('delta_link', 'next-page')",
        [],
    )?;

    let _menu = config_easy::sqlite::builder(&connection)
        .table("app_config")
        .key_column("name")
        .value_column("setting")
        .order_by("display_order")
        .secret_keys(["api_token"])
        .validator(|key, value| {
            if key == "log_level" && !["debug", "info", "warn", "error"].contains(&value) {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::InvalidInput,
                    "expected one of debug, info, warn, error",
                )
                .into());
            }

            Ok(())
        })
        .action("r", "reset delta link", || {
            connection.execute("DELETE FROM sync_state WHERE key = 'delta_link'", [])?;
            println!("Delta link reset.");
            Ok(())
        })
        .run();

    Ok(())
}