openrr_apps_config/
config.rs1use std::{fs, path::PathBuf};
2
3use anyhow::Result;
4use clap::{Parser, ValueEnum};
5use openrr_apps::utils::init_tracing;
6use schemars::schema_for;
7use serde::Deserialize;
8use tracing::debug;
9
10#[derive(Debug, Parser)]
11#[clap(name = env!("CARGO_BIN_NAME"))]
12struct Args {
13 #[clap(subcommand)]
14 subcommand: Subcommand,
15}
16
17#[derive(Debug, Parser)]
18enum Subcommand {
19 Schema {
21 #[clap(value_enum, ignore_case = true)]
23 kind: ConfigKind,
24 },
25 Merge {
26 #[clap(long, value_parser)]
28 config_path: PathBuf,
29 #[clap(long)]
31 config: String,
32 },
33}
34
35#[derive(Debug, Clone, Copy, ValueEnum)]
36enum ConfigKind {
37 RobotConfig,
38 RobotTeleopConfig,
39}
40
41#[derive(Debug, Deserialize)]
42#[serde(untagged)]
43enum Config {
44 RobotConfig(#[allow(dead_code)] Box<openrr_apps::RobotConfig>),
45 RobotTeleopConfig(#[allow(dead_code)] Box<openrr_apps::RobotTeleopConfig>),
46}
47
48fn main() -> Result<()> {
49 init_tracing();
50 let args = Args::parse();
51 debug!(?args);
52
53 match args.subcommand {
54 Subcommand::Schema { kind } => {
55 let schema = match kind {
56 ConfigKind::RobotConfig => schema_for!(openrr_apps::RobotConfig),
57 ConfigKind::RobotTeleopConfig => schema_for!(openrr_apps::RobotTeleopConfig),
58 };
59 println!("{}", serde_json::to_string_pretty(&schema).unwrap());
60 }
61 Subcommand::Merge {
62 config_path,
63 config: overwrite,
64 } => {
65 let s = &fs::read_to_string(config_path)?;
66 let s = &openrr_config::overwrite_str(s, &overwrite)?;
67 let _base: Config = toml::from_str(s)?;
69 println!("{s}");
70 }
71 }
72
73 Ok(())
74}
75
76#[cfg(test)]
77mod tests {
78 use clap::CommandFactory;
79
80 use super::*;
81
82 #[test]
83 fn assert_app() {
84 Args::command().debug_assert();
85 }
86}