greentic_operator/demo/
input.rs1use std::{fs, path::PathBuf};
2
3use anyhow::{Context, Result, anyhow};
4use serde_json::Value as JsonValue;
5use serde_yaml_bw;
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum InputEncoding {
9 Json,
10 Yaml,
11}
12
13impl InputEncoding {
14 pub fn label(self) -> &'static str {
15 match self {
16 InputEncoding::Json => "json",
17 InputEncoding::Yaml => "yaml",
18 }
19 }
20}
21
22#[derive(Debug)]
23pub enum InputSource {
24 Inline(InputEncoding),
25 File {
26 path: PathBuf,
27 encoding: InputEncoding,
28 },
29}
30
31#[derive(Debug)]
32pub struct ParsedInput {
33 pub value: JsonValue,
34 pub source: InputSource,
35}
36
37pub fn parse_input(value: &str) -> Result<ParsedInput> {
38 if let Some(rest) = value.strip_prefix('@') {
39 let path = PathBuf::from(rest);
40 let contents = fs::read_to_string(&path)
41 .with_context(|| format!("unable to read input file {}", path.display()))?;
42 let (value, encoding) = parse_text(&contents)
43 .with_context(|| format!("unable to parse input file {}", path.display()))?;
44 Ok(ParsedInput {
45 value,
46 source: InputSource::File { path, encoding },
47 })
48 } else {
49 let (value, encoding) = parse_text(value)?;
50 Ok(ParsedInput {
51 value,
52 source: InputSource::Inline(encoding),
53 })
54 }
55}
56
57fn parse_text(text: &str) -> Result<(JsonValue, InputEncoding)> {
58 match serde_json::from_str(text) {
59 Ok(value) => Ok((value, InputEncoding::Json)),
60 Err(json_err) => match serde_yaml_bw::from_str(text) {
61 Ok(value) => Ok((value, InputEncoding::Yaml)),
62 Err(yaml_err) => Err(anyhow!(
63 "input parse error: json={json_err}; yaml={yaml_err}"
64 )),
65 },
66 }
67}