use facet::Facet;
use facet_pretty::FacetPretty;
use figue::{self as args, Driver};
#[derive(Debug, Facet)]
struct App {
#[facet(args::named, args::short = 'v', args::counted, default)]
verbose: u8,
#[facet(flatten)]
builtins: args::FigueBuiltins,
#[facet(args::config, args::env_prefix = "KITCHEN")]
settings: Settings,
#[facet(args::subcommand)]
command: Command,
}
#[derive(Debug, Facet)]
struct Settings {
#[facet(default = "figue-kitchen")]
service_name: String,
server: Server,
database: Database,
logging: Logging,
storage: Storage,
#[facet(default)]
tls: Option<Tls>,
}
#[derive(Debug, Facet)]
struct Server {
#[facet(default = "127.0.0.1")]
host: String,
#[facet(default = 8080)]
port: u16,
#[facet(default = 4)]
workers: usize,
}
#[derive(Debug, Facet)]
struct Database {
url: String,
#[facet(default = 16)]
max_connections: u32,
#[facet(default = 30)]
timeout_secs: u64,
}
#[derive(Debug, Facet)]
struct Logging {
#[facet(default = "info")]
level: String,
#[facet(default)]
json: bool,
}
#[derive(Debug, Facet)]
#[facet(rename_all = "kebab-case")]
#[repr(u8)]
#[allow(dead_code)]
enum Storage {
Local {
path: String,
},
S3 {
bucket: String,
#[facet(default = "us-east-1")]
region: String,
#[facet(default)]
endpoint: Option<String>,
},
Memory,
}
#[derive(Debug, Facet)]
struct Tls {
cert_path: String,
key_path: String,
}
#[derive(Debug, Facet)]
#[repr(u8)]
enum Command {
Serve {
#[facet(args::named, default)]
migrate: bool,
},
PrintConfig,
}
fn main() {
let config = args::builder::<App>()
.unwrap()
.cli(|cli| cli.args(std::env::args().skip(1)))
.env(|env| env)
.file(|file| {
file.format(args::JsoncFormat).default_paths([
"crates/figue/examples/kitchen_sink.jsonc",
"crates/figue/examples/kitchen_sink.json",
"kitchen_sink.jsonc",
"kitchen_sink.json",
])
})
.help(|help| {
help.program_name("kitchen-sink")
.version(env!("CARGO_PKG_VERSION"))
.description(
"Search for `database`, `s3`, `default`, `--settings.server.port`, or `KITCHEN__SERVER__PORT`.",
)
})
.build();
let app = Driver::new(config).run().unwrap();
match app.command {
Command::Serve { migrate } => {
println!(
"serving {} with migrate={migrate}",
app.settings.service_name
);
println!("{}", app.pretty());
}
Command::PrintConfig => {
println!("{}", app.pretty());
}
}
}