use crate::prelude::*;
#[injectable]
pub struct ConfigCommand {
audit_options: Ref<AuditOptions>,
batch_options: Ref<BatchOptions>,
cache_options: Ref<CacheOptions>,
config_options: Ref<ConfigOptions>,
copy_options: Ref<CopyOptions>,
cross_config_options: Ref<CrossConfigOptions>,
cross_options: Ref<CrossOptions>,
file_options: Ref<FileOptions>,
queue_add_args: Ref<QueueAddArgs>,
report_options: Ref<ReportOptions>,
runner_options: Ref<RunnerOptions>,
shared_options: Ref<SharedOptions>,
sox_options: Ref<SoxOptions>,
spectrogram_options: Ref<SpectrogramOptions>,
target_options: Ref<TargetOptions>,
upload_options: Ref<UploadOptions>,
verify_options: Ref<VerifyOptions>,
}
impl ConfigCommand {
pub fn execute(&self) -> Result<bool, Failure<ConfigAction>> {
let output = self.render()?;
print!("{output}");
Ok(true)
}
pub fn render(&self) -> Result<String, Failure<ConfigAction>> {
let options = self
.get_options_map()
.map_err(Failure::wrap(ConfigAction::CollateConfig))?;
let docs = Self::get_docs_map();
let mut out = String::new();
for (key, value) in options {
if let Some(field_doc) = docs.get(key.as_str()) {
for line in field_doc.description.split("<br>") {
let _ = writeln!(out, "{}", format_comment(format!("# {line}")));
}
let default = field_doc
.default_doc
.map(String::from)
.or_else(|| field_doc.default_value.clone());
if let Some(default) = default {
let _ = writeln!(out, "{}", format_comment(format!("# Default: {default}")));
}
}
let yaml =
yaml_to_string(&value).map_err(Failure::wrap(ConfigAction::SerializeValue))?;
let yaml = yaml.trim_end_matches('\n');
let is_block = matches!(value, Value::Sequence(s) if !s.is_empty());
let spacer = if is_block { '\n' } else { ' ' };
let _ = writeln!(out, "{}:{spacer}{}", format_key(&key), format_value(yaml));
}
Ok(out)
}
fn get_options_map(&self) -> Result<BTreeMap<String, Value>, YamlError> {
let option_values = [
yaml_to_value(&*self.audit_options)?,
yaml_to_value(&*self.batch_options)?,
yaml_to_value(&*self.cache_options)?,
yaml_to_value(&*self.config_options)?,
yaml_to_value(&*self.copy_options)?,
yaml_to_value(&*self.cross_config_options)?,
yaml_to_value(&*self.cross_options)?,
yaml_to_value(&*self.file_options)?,
yaml_to_value(&*self.queue_add_args)?,
yaml_to_value(&*self.report_options)?,
yaml_to_value(&*self.runner_options)?,
yaml_to_value(&*self.shared_options)?,
yaml_to_value(&*self.sox_options)?,
yaml_to_value(&*self.spectrogram_options)?,
yaml_to_value(&*self.target_options)?,
yaml_to_value(&*self.upload_options)?,
yaml_to_value(&*self.verify_options)?,
];
let mut data = BTreeMap::new();
for value in option_values {
if let Value::Mapping(map) = value {
for (k, v) in map {
if let Value::String(key) = k {
data.insert(key, v);
}
}
}
}
Ok(data)
}
fn get_docs_map() -> HashMap<&'static str, &'static FieldDoc> {
let mut map = HashMap::new();
for doc in OptionsRegistration::get_all() {
for field in &doc.fields {
map.insert(field.config_key, field);
}
}
map
}
}
fn format_comment(input: String) -> ColoredString {
input.green().dimmed()
}
fn format_key(input: &str) -> ColoredString {
input.yellow()
}
fn format_value(input: &str) -> &str {
input
}