plantuml_server_client_rs/
config.rs1pub mod args;
2pub mod file;
3
4use crate::{Args, FileConfig, Format, MetadataVersion, Method, URL_PREFIX};
5use anyhow::Context as _;
6use std::path::PathBuf;
7
8#[derive(Debug)]
10pub struct Config {
11 pub method: Method,
13
14 pub url_prefix: String,
16
17 pub format: Format,
19
20 pub combined: bool,
22
23 pub metadata: Option<PathBuf>,
25
26 pub metadata_version: MetadataVersion,
28}
29
30trait ConfigTrait {
31 fn method(&self) -> Option<Method>;
33
34 fn url_prefix(&self) -> Option<String>;
36
37 fn format(&self) -> Option<Format>;
39
40 fn combined(&self) -> Option<bool>;
42
43 fn metadata_version(&self) -> Option<MetadataVersion>;
45}
46
47macro_rules! overwrite_item {
49 ($config:expr_2021, $args:expr_2021, $from_file:expr_2021, $member:ident) => {
50 let x = $args
51 .$member()
52 .or_else(|| $from_file.as_ref().and_then(|x| x.$member()));
53 if let Some(x) = x {
54 $config.$member = x;
55 }
56 };
57}
58
59impl Config {
60 pub async fn load(args: &Args) -> anyhow::Result<Self> {
62 let from_file = match &args.config {
63 Some(filepath) => {
64 let config = FileConfig::read_from_file(filepath)
65 .await
66 .with_context(|| {
67 format!("failed to read `{filepath:?}` that specified by args.")
68 })?;
69 Some(config)
70 }
71 None => FileConfig::read_from_default_path().await,
72 };
73
74 Self::merge_from(args, from_file)
75 }
76
77 fn merge_from(args: &Args, from_file: Option<FileConfig>) -> anyhow::Result<Self> {
82 let mut config = Self::default();
83
84 overwrite_item!(config, args, from_file, method);
85 overwrite_item!(config, args, from_file, url_prefix);
86 overwrite_item!(config, args, from_file, format);
87 overwrite_item!(config, args, from_file, combined);
88 config.metadata = args.metadata.clone();
89 overwrite_item!(config, args, from_file, metadata_version);
90
91 if config.metadata.is_some() && config.metadata_version.is_v1() {
92 tracing::warn!(
93 "The `v1` metadata format is deprecated. Please specify `--metadata-version v2` and change post process."
94 );
95 }
96
97 Ok(config)
98 }
99}
100
101impl Default for Config {
102 fn default() -> Self {
103 Self {
104 method: Method::Get,
105 url_prefix: URL_PREFIX.into(),
106 format: Format::Svg,
107 combined: false,
108 metadata: None,
109 metadata_version: MetadataVersion::V1,
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 use clap::Parser;
119
120 #[test]
121 fn test_combined() -> anyhow::Result<()> {
122 let mut args = Args::parse();
124 args.combined = false;
125 let from_file: FileConfig = toml::from_str("[pscr]\ncombined = false")?;
126 let config = Config::merge_from(&args, Some(from_file))?;
127 assert!(!config.combined);
128
129 let mut args = Args::parse();
131 args.combined = false;
132 let from_file: FileConfig = toml::from_str("[pscr]\ncombined = true")?;
133 let config = Config::merge_from(&args, Some(from_file))?;
134 assert!(config.combined);
135
136 let mut args = Args::parse();
138 args.combined = false;
139 let from_file: FileConfig = toml::from_str("[pscr]")?;
140 let config = Config::merge_from(&args, Some(from_file))?;
141 assert!(!config.combined);
142
143 let mut args = Args::parse();
145 args.combined = true;
146 let from_file: FileConfig = toml::from_str("[pscr]\ncombined = false")?;
147 let config = Config::merge_from(&args, Some(from_file))?;
148 assert!(config.combined);
149
150 let mut args = Args::parse();
152 args.combined = true;
153 let from_file: FileConfig = toml::from_str("[pscr]\ncombined = true")?;
154 let config = Config::merge_from(&args, Some(from_file))?;
155 assert!(config.combined);
156
157 let mut args = Args::parse();
159 args.combined = true;
160 let from_file: FileConfig = toml::from_str("[pscr]")?;
161 let config = Config::merge_from(&args, Some(from_file))?;
162 assert!(config.combined);
163
164 Ok(())
165 }
166}