cli: move to_toml_value() to src/config.rs

Google would like to use `to_toml_value()` for writing TOML-formatted
configs from our internal bug report command.
This commit is contained in:
Martin von Zweigbergk 2024-05-28 22:33:14 -07:00 committed by Martin von Zweigbergk
parent 8a4087d07b
commit ec5914c830
2 changed files with 29 additions and 29 deletions

View file

@ -12,15 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fmt;
use std::io::Write;
use itertools::Itertools;
use tracing::instrument;
use crate::cli_util::{get_new_config_file_path, run_ui_editor, CommandHelper};
use crate::command_error::{config_error, user_error, CommandError};
use crate::config::{write_config_value_to_file, AnnotatedValue, ConfigNamePathBuf, ConfigSource};
use crate::config::{
to_toml_value, write_config_value_to_file, AnnotatedValue, ConfigNamePathBuf, ConfigSource,
};
use crate::generic_templater::GenericTemplateLanguage;
use crate::template_builder::TemplateLanguage as _;
use crate::templater::TemplatePropertyExt as _;
@ -166,32 +166,6 @@ pub(crate) fn cmd_config(
}
}
fn to_toml_value(value: &config::Value) -> Result<toml_edit::Value, config::ConfigError> {
fn type_error<T: fmt::Display>(message: T) -> config::ConfigError {
config::ConfigError::Message(message.to_string())
}
// It's unlikely that the config object contained unsupported values, but
// there's no guarantee. For example, values coming from environment
// variables might be big int.
match value.kind {
config::ValueKind::Nil => Err(type_error(format!("Unexpected value: {value}"))),
config::ValueKind::Boolean(v) => Ok(v.into()),
config::ValueKind::I64(v) => Ok(v.into()),
config::ValueKind::I128(v) => Ok(i64::try_from(v).map_err(type_error)?.into()),
config::ValueKind::U64(v) => Ok(i64::try_from(v).map_err(type_error)?.into()),
config::ValueKind::U128(v) => Ok(i64::try_from(v).map_err(type_error)?.into()),
config::ValueKind::Float(v) => Ok(v.into()),
config::ValueKind::String(ref v) => Ok(v.into()),
// TODO: Remove sorting when config crate maintains deterministic ordering.
config::ValueKind::Table(ref table) => table
.iter()
.sorted_by_key(|(k, _)| *k)
.map(|(k, v)| Ok((k, to_toml_value(v)?)))
.collect(),
config::ValueKind::Array(ref array) => array.iter().map(to_toml_value).collect(),
}
}
// AnnotatedValue will be cloned internally in the templater. If the cloning
// cost matters, wrap it with Rc.
fn config_template_language() -> GenericTemplateLanguage<'static, AnnotatedValue> {

View file

@ -27,6 +27,32 @@ use tracing::instrument;
use crate::command_error::{user_error, user_error_with_message, CommandError};
pub fn to_toml_value(value: &config::Value) -> Result<toml_edit::Value, config::ConfigError> {
fn type_error<T: fmt::Display>(message: T) -> config::ConfigError {
config::ConfigError::Message(message.to_string())
}
// It's unlikely that the config object contained unsupported values, but
// there's no guarantee. For example, values coming from environment
// variables might be big int.
match value.kind {
config::ValueKind::Nil => Err(type_error(format!("Unexpected value: {value}"))),
config::ValueKind::Boolean(v) => Ok(v.into()),
config::ValueKind::I64(v) => Ok(v.into()),
config::ValueKind::I128(v) => Ok(i64::try_from(v).map_err(type_error)?.into()),
config::ValueKind::U64(v) => Ok(i64::try_from(v).map_err(type_error)?.into()),
config::ValueKind::U128(v) => Ok(i64::try_from(v).map_err(type_error)?.into()),
config::ValueKind::Float(v) => Ok(v.into()),
config::ValueKind::String(ref v) => Ok(v.into()),
// TODO: Remove sorting when config crate maintains deterministic ordering.
config::ValueKind::Table(ref table) => table
.iter()
.sorted_by_key(|(k, _)| *k)
.map(|(k, v)| Ok((k, to_toml_value(v)?)))
.collect(),
config::ValueKind::Array(ref array) => array.iter().map(to_toml_value).collect(),
}
}
#[derive(Error, Debug)]
pub enum ConfigError {
#[error(transparent)]