1use crate::format::Indentation;
2use derive_getters::Getters;
3use derive_more::Display;
4use serde_json::Value;
5use std::borrow::Cow;
6use thiserror::Error;
7
8pub mod format;
9
10#[derive(Debug, Error)]
11pub enum Error {
12 #[error("json parsing error: {0}")]
13 Json(#[from] serde_json::Error),
14 #[error("yaml parsing error: {0}")]
15 Yaml(#[from] serde_yaml::Error),
16 #[error("format error: {0}")]
17 Format(#[from] format::Error),
18}
19
20#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Display)]
21pub enum DataType {
22 Json,
23 Yaml,
24}
25
26#[derive(Debug, Getters, Clone, Hash, PartialEq, Eq)]
28pub struct Data<'a> {
29 payload: Cow<'a, str>,
30 data_type: DataType,
31}
32
33impl<'a> Data<'a> {
34 pub fn json(data: Cow<'a, str>) -> Self {
35 Self {
36 payload: data,
37 data_type: DataType::Json,
38 }
39 }
40
41 pub fn yaml(data: Cow<'a, str>) -> Self {
42 Self {
43 payload: data,
44 data_type: DataType::Yaml,
45 }
46 }
47
48 pub fn pretty_from_value(
49 value: &Value,
50 data_type: DataType,
51 indentation: Indentation,
52 ) -> Result<Self, Error> {
53 let payload = data_type.pretty_format(value, indentation)?;
54 Ok(Self {
55 payload: Cow::Owned(payload),
56 data_type,
57 })
58 }
59 pub fn pretty_convert_to(
60 &self,
61 target_type: DataType,
62 indentation: Indentation,
63 ) -> Result<Data, Error> {
64 let value = Value::try_from(self)?;
65 let payload = target_type.pretty_format(&value, indentation)?;
66 let data = Self {
67 payload: Cow::Owned(payload),
68 data_type: target_type,
69 };
70 Ok(data)
71 }
72
73 pub fn pretty_format(&'a self, indentation: Indentation) -> Result<Self, Error> {
74 let value = Value::try_from(self)?;
75 let payload = self.data_type.pretty_format(&value, indentation)?;
76 Ok(Self {
77 payload: Cow::Owned(payload),
78 data_type: self.data_type,
79 })
80 }
81
82 pub fn into_inner(self) -> Cow<'a, str> {
83 self.payload
84 }
85
86 pub fn into_owned(self) -> Data<'static> {
87 Data {
88 payload: Cow::Owned(self.payload.into_owned()),
89 data_type: self.data_type,
90 }
91 }
92}
93
94impl DataType {
95 pub fn value_from_str(&self, data: &str) -> Result<Value, Error> {
96 let result = match self {
97 DataType::Json => serde_json::from_str(data)?,
98 DataType::Yaml => serde_yaml::from_str(data)?,
99 };
100 Ok(result)
101 }
102}
103
104impl TryFrom<&Data<'_>> for Value {
105 type Error = Error;
106
107 fn try_from(data: &Data) -> Result<Self, Self::Error> {
108 data.data_type.value_from_str(&data.payload)
109 }
110}