1use crate::{parser, printer};
2use indexmap::IndexMap;
3use nom::{
4 error::{ErrorKind, ParseError, VerboseError},
5 Finish,
6};
7use std::{fmt::Write, str::FromStr};
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub enum ArrayType {
11 Array,
12 List,
13}
14
15#[derive(Clone, Debug, PartialEq)]
16pub enum Value {
17 Bool(bool),
18 Int(i64),
19 Float(f64),
20 String(String),
21 Array(Vec<Value>, ArrayType),
22 Object(IndexMap<String, Value>),
23}
24
25impl ToString for Value {
26 fn to_string(&self) -> String {
27 let mut res = String::new();
28 write!(&mut res, "config : ").unwrap();
29 printer::print(&mut res, self, 4);
30 write!(&mut res, ";").unwrap();
31 res
32 }
33}
34
35impl FromStr for Value {
36 type Err = String;
37
38 fn from_str(input: &str) -> Result<Self, Self::Err> {
39 parser::root::<VerboseError<&str>>(input)
40 .finish()
41 .map(|(_, o)| o)
42 .map_err(|e| format!("{e}"))
43 }
44}
45
46impl Value {
47 pub fn obj_from_str(input: &str) -> Result<IndexMap<String, Value>, VerboseError<&str>> {
48 parser::root::<VerboseError<&str>>(input)
49 .finish()
50 .and_then(|(_, o)| match o {
51 Value::Object(map) => Ok(map),
52 _ => Err(VerboseError::from_error_kind(
53 "Config did not have a object in the root",
54 ErrorKind::Fail,
55 )),
56 })
57 }
58
59 #[inline]
60 pub fn as_bool(&self) -> Option<&bool> {
61 match self {
62 Value::Bool(v) => Some(v),
63 _ => None,
64 }
65 }
66
67 #[inline]
68 pub fn as_bool_mut(&mut self) -> Option<&mut bool> {
69 match self {
70 Value::Bool(v) => Some(v),
71 _ => None,
72 }
73 }
74
75 #[inline]
76 pub fn as_int(&self) -> Option<&i64> {
77 match self {
78 Value::Int(v) => Some(v),
79 _ => None,
80 }
81 }
82
83 #[inline]
84 pub fn as_int_mut(&mut self) -> Option<&mut i64> {
85 match self {
86 Value::Int(v) => Some(v),
87 _ => None,
88 }
89 }
90
91 #[inline]
92 pub fn as_float(&self) -> Option<&f64> {
93 match self {
94 Value::Float(v) => Some(v),
95 _ => None,
96 }
97 }
98
99 #[inline]
100 pub fn as_float_mut(&mut self) -> Option<&mut f64> {
101 match self {
102 Value::Float(v) => Some(v),
103 _ => None,
104 }
105 }
106
107 #[inline]
108 pub fn as_str(&self) -> Option<&str> {
109 match self {
110 Value::String(v) => Some(v),
111 _ => None,
112 }
113 }
114
115 #[inline]
116 pub fn as_str_mut(&mut self) -> Option<&mut String> {
117 match self {
118 Value::String(v) => Some(v),
119 _ => None,
120 }
121 }
122
123 #[inline]
124 pub fn as_vec(&self) -> Option<&Vec<Value>> {
125 match self {
126 Value::Array(v, _) => Some(v),
127 _ => None,
128 }
129 }
130
131 #[inline]
132 pub fn as_vec_mut(&mut self) -> Option<&mut Vec<Value>> {
133 match self {
134 Value::Array(v, _) => Some(v),
135 _ => None,
136 }
137 }
138
139 #[inline]
140 pub fn as_obj(&self) -> Option<&IndexMap<String, Value>> {
141 match self {
142 Value::Object(v) => Some(v),
143 _ => None,
144 }
145 }
146
147 #[inline]
148 pub fn as_obj_mut(&mut self) -> Option<&mut IndexMap<String, Value>> {
149 match self {
150 Value::Object(v) => Some(v),
151 _ => None,
152 }
153 }
154}