cfgrs/
lib.rs

1//! This is the library documentation for code which is used in the binary `cfgrs`, which is likely
2//! what you're looking for.
3//! This can be found at https://github.com/tveness/cfgrs/releases
4//! or alternatively can be installed with `cargo install cfgrs`.
5//!
6//!
7//! cfgrs is a small CLI helper tool for converting between different configuration formats.
8//! The current formats supported are:
9//! * hcl
10//! * json
11//! * toml
12//! * yaml
13//!
14//! These formats are not completely interchangeable, and as such if they cannot
15//! be converted an error is currently raised.
16//!
17//! cfgrs may be used in the following way to convert between formats:
18//! ```bash
19//! cat Cargo.toml|cfgrs -o yaml
20//! ```
21//! which will then display a Cargo.toml file in its yaml representation (if this is possible)
22
23use serde::Serialize;
24use std::str::FromStr;
25
26#[derive(Debug)]
27/// Lists different configuration file formats supported
28pub enum ConfigType {
29    Json,
30    Yaml,
31    Toml,
32    Hcl,
33}
34
35#[derive(Debug, Serialize)]
36#[serde(untagged)]
37/// Wrapper for the different crates' parsed input e.g. `serde_json::Value` gets wrapped by `Json`
38pub enum ParsedInput {
39    Json(serde_json::Value),
40    Yaml(serde_yaml::Value),
41    Toml(toml::Value),
42    Hcl(hcl::Body),
43}
44
45/// Error type for parsing input
46#[derive(Debug)]
47pub struct ParseConfigError {}
48
49impl std::fmt::Display for ParseConfigError {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        write!(f, "Failed to parse as valid hcl, json, yaml, toml")
52    }
53}
54
55impl std::error::Error for ParseConfigError {
56    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
57        None
58    }
59}
60
61impl FromStr for ParsedInput {
62    type Err = ParseConfigError;
63
64    fn from_str(s: &str) -> std::prelude::v1::Result<Self, Self::Err> {
65        // Attempt to parse the string with each of the parsers
66        if let Ok(parsed) = serde_json::from_str(s) {
67            Ok(ParsedInput::Json(parsed))
68        } else if let Ok(parsed) = serde_yaml::from_str(s) {
69            Ok(ParsedInput::Yaml(parsed))
70        } else if let Ok(parsed) = toml::from_str(s) {
71            Ok(ParsedInput::Toml(parsed))
72        } else if let Ok(parsed) = hcl::from_str(s) {
73            Ok(ParsedInput::Hcl(parsed))
74        } else {
75            Err(ParseConfigError {})
76        }
77    }
78}