blob: 5f0e7043c86c672cc487881e6c700a57d976ef8f [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use anyhow::{Context, Error};
use argh::FromArgs;
use cm_rust::FidlIntoNative;
use fidl::encoding::decode_persistent;
use fidl_fuchsia_component_config as fconfig;
use std::{collections::BTreeMap, path::PathBuf};
/// dump configuration values for a component in a human-readable format
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "dump-values")]
pub struct DumpValues {
/// path to the compiled manifest
#[argh(option)]
cm: PathBuf,
/// path to the configuration value file
#[argh(option)]
cvf: PathBuf,
/// path to the JSON output, print to stdout if not provided
#[argh(option)]
output: Option<PathBuf>,
}
impl DumpValues {
pub fn dump(self) -> Result<(), Error> {
let DumpValues { cm, cvf, output } = self;
let decl = crate::common::load_manifest(&cm).context("loading compiled manifest")?;
let config_decl = decl.config.context("component must declare a config schema")?;
let cvf_bytes =
std::fs::read(&cvf).with_context(|| format!("reading {}", cvf.display()))?;
let values: fconfig::ValuesData =
decode_persistent(&cvf_bytes).context("decoding value file")?;
let values = values.fidl_into_native();
let resolved = config_encoder::ConfigFields::resolve(&config_decl, values)
.context("resolving config values")?;
let fields_map = resolved
.fields
.into_iter()
.map(|f| (f.key, json_value_from_config_value(f.value)))
.collect::<BTreeMap<_, _>>();
let for_humans = serde_json::to_string_pretty(&fields_map)
.context("serializing config values as json")?;
if let Some(output) = output {
std::fs::write(&output, for_humans)
.with_context(|| format!("writing to {}", output.display()))?;
} else {
println!("{}", for_humans);
}
Ok(())
}
}
fn json_value_from_config_value(v: cm_rust::Value) -> serde_json::Value {
match v {
cm_rust::Value::Single(s) => match s {
cm_rust::SingleValue::Bool(b) => serde_json::Value::Bool(b),
cm_rust::SingleValue::Uint8(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Uint16(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Uint32(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Uint64(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Int8(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Int16(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Int32(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::Int64(n) => serde_json::Value::Number(n.into()),
cm_rust::SingleValue::String(s) => serde_json::Value::String(s),
},
cm_rust::Value::Vector(v) => match v {
cm_rust::VectorValue::BoolVector(bv) => serde_json::Value::Array(
bv.into_iter().map(|b| serde_json::Value::Bool(b)).collect(),
),
cm_rust::VectorValue::Uint8Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Uint16Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Uint32Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Uint64Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Int8Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Int16Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Int32Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::Int64Vector(nv) => serde_json::Value::Array(
nv.into_iter().map(|n| serde_json::Value::Number(n.into())).collect(),
),
cm_rust::VectorValue::StringVector(sv) => serde_json::Value::Array(
sv.into_iter().map(|s| serde_json::Value::String(s)).collect(),
),
},
}
}