mirror of
https://github.com/OMGeeky/confique.git
synced 2026-01-02 17:46:29 +01:00
Implement Serialize for meta::Expr and use it in PrintExpr
This probably fixes a few edge case bugs (float infinity and stuff) and results in less code.
This commit is contained in:
@@ -47,7 +47,8 @@ pub enum LeafKind {
|
||||
Optional,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Expr {
|
||||
Str(&'static str),
|
||||
Float(Float),
|
||||
@@ -56,13 +57,15 @@ pub enum Expr {
|
||||
Array(&'static [Expr]),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Float {
|
||||
F32(f32),
|
||||
F64(f64),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Integer {
|
||||
U8(u8),
|
||||
U16(u16),
|
||||
|
||||
27
src/toml.rs
27
src/toml.rs
@@ -216,26 +216,17 @@ fn format_impl(
|
||||
/// Helper to emit `meta::Expr` into TOML.
|
||||
struct PrintExpr(&'static Expr);
|
||||
|
||||
impl From<&'static Expr> for PrintExpr {
|
||||
fn from(expr: &'static Expr) -> Self {
|
||||
Self(expr)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PrintExpr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self.0 {
|
||||
Expr::Str(v) => toml::Value::String(v.to_owned()).fmt(f),
|
||||
Expr::Float(v) => v.fmt(f),
|
||||
Expr::Integer(v) => v.fmt(f),
|
||||
Expr::Bool(v) => v.fmt(f),
|
||||
Expr::Array(items) => {
|
||||
// TODO: pretty printing of long arrays onto multiple lines?
|
||||
f.write_char('[')?;
|
||||
for (i, item) in items.iter().enumerate() {
|
||||
if i != 0 {
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
PrintExpr(item).fmt(f)?;
|
||||
}
|
||||
f.write_char(']')?;
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
toml::to_string(&self.0)
|
||||
.expect("string serialization to TOML failed")
|
||||
.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
28
src/yaml.rs
28
src/yaml.rs
@@ -201,19 +201,8 @@ struct PrintExpr(&'static Expr);
|
||||
impl fmt::Display for PrintExpr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self.0 {
|
||||
Expr::Str(v) => {
|
||||
// This is a bit ugly. Sadly, no YAML crate in our dependency
|
||||
// tree has an API to serialize a string only, without emitting
|
||||
// the `---` at the start of the document. But instead of
|
||||
// implementing the quoting logic ourselves (which is really
|
||||
// complicated as it turns out!), we use this hack.
|
||||
let value = serde_yaml::Value::String(v.to_owned());
|
||||
let serialized = serde_yaml::to_string(&value).unwrap();
|
||||
serialized[4..].trim_end_matches('\n').fmt(f)
|
||||
},
|
||||
Expr::Float(v) => v.fmt(f),
|
||||
Expr::Integer(v) => v.fmt(f),
|
||||
Expr::Bool(v) => v.fmt(f),
|
||||
// We have to special case arrays as the normal formatter only emits
|
||||
// multi line lists.
|
||||
Expr::Array(items) => {
|
||||
// TODO: pretty printing of long arrays onto multiple lines?
|
||||
f.write_char('[')?;
|
||||
@@ -226,6 +215,19 @@ impl fmt::Display for PrintExpr {
|
||||
f.write_char(']')?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// All these other types can simply be serialized as is.
|
||||
Expr::Str(_) | Expr::Float(_) | Expr::Integer(_) | Expr::Bool(_) => {
|
||||
let out = serde_yaml::to_string(&self.0).expect("string serialization to YAML failed");
|
||||
|
||||
// Unfortunately, `serde_yaml` cannot serialize these values on its own
|
||||
// without embedding them in a full document (starting with `---` and
|
||||
// ending with a newline). So we need to cleanup.
|
||||
out.strip_prefix("---\n")
|
||||
.unwrap_or(&out)
|
||||
.trim_matches('\n')
|
||||
.fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user