Skip to content

Commit

Permalink
feat: add support for YAML and JSON to the generate command (vectordo…
Browse files Browse the repository at this point in the history
…tdev#18345)

* feat: add support for YAML and JSON to the generate command

* tweaks and pretty print

* delete comments

* more tests
  • Loading branch information
pront authored Aug 23, 2023
1 parent 2f458f6 commit e15aec7
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 132 deletions.
16 changes: 9 additions & 7 deletions src/config/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,10 @@ mod tests {
use serde_json::json;
use vector_config::component::{SinkDescription, SourceDescription, TransformDescription};

use crate::config::Format;
use crate::{
config::{cmd::serialize_to_json, vars, ConfigBuilder},
generate,
generate::{generate_example, TransformInputsStrategy},
};

Expand Down Expand Up @@ -325,13 +327,13 @@ mod tests {
.collect::<Vec<_>>()
.join(","),
);
generate_example(
false,
generate_config_str.as_ref(),
&None,
TransformInputsStrategy::All,
)
.expect("invalid config generated")
let opts = generate::Opts {
fragment: true,
expression: generate_config_str.to_string(),
file: None,
format: Format::Toml,
};
generate_example(&opts, TransformInputsStrategy::All).expect("invalid config generated")
}

proptest! {
Expand Down
38 changes: 36 additions & 2 deletions src/config/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![deny(missing_docs, missing_debug_implementations)]

use std::path::Path;
use std::str::FromStr;

use serde::de;

Expand All @@ -21,6 +22,19 @@ pub enum Format {
Yaml,
}

impl FromStr for Format {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"toml" => Ok(Format::Toml),
"yaml" => Ok(Format::Yaml),
"json" => Ok(Format::Json),
_ => Err(format!("Invalid format: {}", s)),
}
}
}

impl Format {
/// Obtain the format from the file path using extension as a hint.
pub fn from_path<T: AsRef<Path>>(path: T) -> Result<Self, T> {
Expand All @@ -34,8 +48,6 @@ impl Format {
}

/// Parse the string represented in the specified format.
/// If the format is unknown - fallback to the default format and attempt
/// parsing using that.
pub fn deserialize<T>(content: &str, format: Format) -> Result<T, Vec<String>>
where
T: de::DeserializeOwned,
Expand All @@ -47,9 +59,31 @@ where
}
}

/// Serialize the specified `value` into a string.
pub fn serialize<T>(value: &T, format: Format) -> Result<String, String>
where
T: serde::ser::Serialize,
{
match format {
Format::Toml => toml::to_string(value).map_err(|e| e.to_string()),
Format::Yaml => serde_yaml::to_string(value).map_err(|e| e.to_string()),
Format::Json => serde_json::to_string_pretty(value).map_err(|e| e.to_string()),
}
}

#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;

impl Arbitrary for Format {
type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
prop_oneof![Just(Format::Toml), Just(Format::Json), Just(Format::Yaml),].boxed()
}

type Strategy = BoxedStrategy<Self>;
}

/// This test ensures the logic to guess file format from the file path
/// works correctly.
Expand Down
Loading

0 comments on commit e15aec7

Please sign in to comment.