hocon_rs/raw/
raw_value.rs1use 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}