hocon_rs/raw/
raw_value.rs

1use crate::Result;
2use crate::raw::add_assign::AddAssign;
3use crate::raw::concat::Concat;
4use crate::raw::field::ObjectField;
5use crate::raw::include::Inclusion;
6use crate::raw::raw_array::RawArray;
7use crate::raw::raw_object::RawObject;
8use crate::raw::raw_string::RawString;
9use crate::raw::substitution::Substitution;
10use serde_json::Number;
11use std::fmt::{Display, Formatter};
12
13pub const RAW_OBJECT_TYPE: &str = "object";
14pub const RAW_ARRAY_TYPE: &str = "array";
15pub const RAW_BOOLEAN_TYPE: &str = "boolean";
16pub const RAW_NULL_TYPE: &str = "null";
17pub const RAW_QUOTED_STRING_TYPE: &str = "quoted_string";
18pub const RAW_UNQUOTED_STRING_TYPE: &str = "unquoted_string";
19pub const RAW_MULTILINE_STRING_TYPE: &str = "multiline_string";
20pub const RAW_CONCAT_STRING_TYPE: &str = "concat_string";
21pub const RAW_NUMBER_TYPE: &str = "number";
22pub const RAW_SUBSTITUTION_TYPE: &str = "substitution";
23pub const RAW_CONCAT_TYPE: &str = "concat";
24pub const RAW_ADD_ASSIGN_TYPE: &str = "add_assign";
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash)]
27pub enum RawValue {
28    Object(RawObject),
29    Array(RawArray),
30    Boolean(bool),
31    Null,
32    String(RawString),
33    Number(Number),
34    Substitution(Substitution),
35    Concat(Concat),
36    AddAssign(AddAssign),
37}
38
39impl RawValue {
40    pub fn ty(&self) -> &'static str {
41        match self {
42            RawValue::Object(_) => RAW_OBJECT_TYPE,
43            RawValue::Array(_) => RAW_ARRAY_TYPE,
44            RawValue::Boolean(_) => RAW_BOOLEAN_TYPE,
45            RawValue::Null => RAW_NULL_TYPE,
46            RawValue::String(s) => s.ty(),
47            RawValue::Number(_) => RAW_NUMBER_TYPE,
48            RawValue::Substitution(_) => RAW_SUBSTITUTION_TYPE,
49            RawValue::Concat(_) => RAW_CONCAT_TYPE,
50            RawValue::AddAssign(_) => RAW_ADD_ASSIGN_TYPE,
51        }
52    }
53
54    pub fn is_simple_value(&self) -> bool {
55        matches!(
56            self,
57            RawValue::Boolean(_) | RawValue::Null | RawValue::String(_) | RawValue::Number(_)
58        ) || matches!(self, RawValue::AddAssign(r) if r.is_simple_value())
59    }
60
61    pub fn inclusion(inclusion: Inclusion) -> RawValue {
62        let field = ObjectField::inclusion(inclusion);
63        RawValue::Object(RawObject::new(vec![field]))
64    }
65
66    pub fn object(values: Vec<(RawString, RawValue)>) -> RawValue {
67        let fields = values
68            .into_iter()
69            .map(|(k, v)| ObjectField::key_value(k, v))
70            .collect();
71        RawValue::Object(RawObject::new(fields))
72    }
73
74    pub fn array(values: Vec<RawValue>) -> RawValue {
75        RawValue::Array(RawArray::new(values))
76    }
77
78    pub fn boolean(b: bool) -> RawValue {
79        RawValue::Boolean(b)
80    }
81
82    pub fn null() -> RawValue {
83        RawValue::Null
84    }
85
86    pub fn quoted_string(s: impl Into<String>) -> RawValue {
87        RawValue::String(RawString::quoted(s))
88    }
89
90    pub fn unquoted_string(s: impl Into<String>) -> RawValue {
91        RawValue::String(RawString::unquoted(s))
92    }
93
94    pub fn multiline_string(s: impl Into<String>) -> RawValue {
95        RawValue::String(RawString::multiline(s))
96    }
97
98    pub fn path_expression(paths: Vec<RawString>) -> RawValue {
99        RawValue::String(RawString::path_expression(paths))
100    }
101
102    pub fn number(n: impl Into<Number>) -> RawValue {
103        RawValue::Number(n.into())
104    }
105
106    pub fn substitution(s: Substitution) -> RawValue {
107        RawValue::Substitution(s)
108    }
109
110    pub fn concat(values: Vec<RawValue>, spaces: Vec<Option<String>>) -> Result<RawValue> {
111        Ok(RawValue::Concat(Concat::new(values, spaces)?))
112    }
113
114    pub fn add_assign(v: RawValue) -> RawValue {
115        RawValue::AddAssign(AddAssign::new(v.into()))
116    }
117}
118
119impl Display for RawValue {
120    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
121        match self {
122            RawValue::Object(object) => write!(f, "{}", object),
123            RawValue::Array(array) => write!(f, "{}", array),
124            RawValue::Boolean(boolean) => write!(f, "{}", boolean),
125            RawValue::Null => write!(f, "null"),
126            RawValue::String(string) => write!(f, "{}", string),
127            RawValue::Number(number) => write!(f, "{}", number),
128            RawValue::Substitution(substitution) => write!(f, "{}", substitution),
129            RawValue::Concat(concat) => write!(f, "{}", concat),
130            RawValue::AddAssign(add_assign) => write!(f, "{}", add_assign),
131        }
132    }
133}
134
135impl TryInto<RawArray> for RawValue {
136    type Error = crate::error::Error;
137
138    fn try_into(self) -> Result<RawArray> {
139        match self {
140            RawValue::Array(a) => Ok(a),
141            other => Err(crate::error::Error::InvalidConversion {
142                from: other.ty(),
143                to: RAW_ARRAY_TYPE,
144            }),
145        }
146    }
147}
148
149impl TryInto<RawObject> for RawValue {
150    type Error = crate::error::Error;
151
152    fn try_into(self) -> Result<RawObject> {
153        match self {
154            RawValue::Object(o) => Ok(o),
155            other => Err(crate::error::Error::InvalidConversion {
156                from: other.ty(),
157                to: RAW_OBJECT_TYPE,
158            }),
159        }
160    }
161}
162
163impl From<serde_json::Value> for RawValue {
164    fn from(val: serde_json::Value) -> Self {
165        match val {
166            serde_json::Value::Null => RawValue::Null,
167            serde_json::Value::Bool(boolean) => RawValue::Boolean(boolean),
168            serde_json::Value::Number(number) => RawValue::Number(number),
169            serde_json::Value::String(string) => RawValue::String(string.into()),
170            serde_json::Value::Array(values) => {
171                RawValue::array(values.into_iter().map(Into::into).collect())
172            }
173            serde_json::Value::Object(map) => {
174                let fields = map
175                    .into_iter()
176                    .map(|(key, value)| ObjectField::key_value(key, value))
177                    .collect();
178                let raw_object = RawObject::new(fields);
179                RawValue::Object(raw_object)
180            }
181        }
182    }
183}