1use std::{error::Error, fmt::Display, str::FromStr};
2use crate::error::{LibError, LibErrorContext};
3use super::LibExpr;
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum LibAst {
7 LibGroup {
8 kind: String,
9 params: Vec<String>,
10 items: Vec<LibAst>,
11 },
12 Attr {
13 key: String,
14 value: LibValue,
15 },
16}
17
18#[derive(Debug, Clone, PartialEq)]
19pub enum LibValue {
20 Bool(bool),
21 Float(f64),
22 String(String),
23 Ident(String),
24 Vec(Vec<LibValue>),
25}
26
27impl LibAst {
28 pub fn group(kind: impl Into<String>, params: impl Into<Vec<String>>, items: impl Into<Vec<LibAst>>) -> Self {
29 Self::LibGroup {
30 kind: kind.into(),
31 params: params.into(),
32 items: items.into(),
33 }
34 }
35
36 pub fn group_single_param(kind: impl Into<String>, param: impl Into<String>, items: impl Into<Vec<LibAst>>) -> Self {
37 Self::LibGroup {
38 kind: kind.into(),
39 params: vec![param.into()],
40 items: items.into(),
41 }
42 }
43
44 pub fn attr(key: impl Into<String>, value: impl Into<LibValue>) -> Self {
45 Self::Attr { key: key.into(), value: value.into() }
46 }
47}
48
49impl LibValue {
50 pub fn kind_str(&self) -> &'static str {
51 match self {
52 Self::Bool(_) => "bool",
53 Self::Float(_) => "float",
54 Self::Ident(_) => "ident",
55 Self::String(_) => "string",
56 Self::Vec(_) => "vector",
57 }
58 }
59
60 pub fn bool(&self) -> Result<bool, LibError> {
61 if let Self::Bool(value) = self {
62 Ok(*value)
63 } else {
64 Err(LibError::ValueKindUnmatch("bool", self.kind_str()))
65 }
66 }
67
68 pub fn float(&self) -> Result<f64, LibError> {
69 if let Self::Float(value) = self {
70 Ok(*value)
71 } else {
72 Err(LibError::ValueKindUnmatch("float", self.kind_str()))
73 }
74 }
75
76 pub fn floats(&self) -> Result<Vec<f64>, LibError> {
77 if let Self::String(value) = self {
78 let values = value
79 .split(',')
80 .map(|token| token.trim().parse::<f64>().map_err(|e| LibError::ParseFloat(e)))
81 .collect::<Result<Vec<_>, _>>()
82 .context(|| "parse float from strings")?;
83 Ok(values)
84 } else {
85 Err(LibError::ValueKindUnmatch("floats", self.kind_str()))
86 }
87 }
88
89 pub fn expr(&self) -> Result<LibExpr, LibError> {
90 if let Self::String(value) = self {
91 let expr = LibExpr::from_str(value)?;
92 Ok(expr)
93 } else {
94 Err(LibError::ValueKindUnmatch("expr", self.kind_str()))
95 }
96 }
97
98 pub fn ident(&self) -> Result<&str, LibError> {
99 if let Self::Ident(value) = self {
100 Ok(value)
101 } else {
102 Err(LibError::ValueKindUnmatch("ident", self.kind_str()))
103 }
104 }
105
106 pub fn literal(&self) -> Result<&str, LibError> {
107 match self {
108 Self::Ident(value) => Ok(value),
109 Self::String(value) => Ok(value),
110 _ => Err(LibError::ValueKindUnmatch("literal", self.kind_str()))
111 }
112 }
113
114 pub fn string(&self) -> Result<&str, LibError> {
115 if let Self::String(value) = self {
116 Ok(value)
117 } else {
118 Err(LibError::ValueKindUnmatch("string", self.kind_str()))
119 }
120 }
121
122 pub fn vector(&self) -> Result<&[LibValue], LibError> {
123 if let Self::Vec(value) = self {
124 Ok(value)
125 } else {
126 Err(LibError::ValueKindUnmatch("vector", self.kind_str()))
127 }
128 }
129
130 pub fn parse<T>(&self) -> Result<T, LibError>
131 where
132 T: FromStr,
133 T::Err: Error,
134 {
135 let s = self.ident()?;
136 T::from_str(s).map_err(|e| LibError::Parse(e.to_string()))
137 }
138}
139
140impl LibValue {
141 pub fn into_bool(self) -> Result<bool, LibError> {
142 if let Self::Bool(value) = self {
143 Ok(value)
144 } else {
145 Err(LibError::ValueKindUnmatch("bool", self.kind_str()))
146 }
147 }
148
149 pub fn into_float(self) -> Result<f64, LibError> {
150 if let Self::Float(value) = self {
151 Ok(value)
152 } else {
153 Err(LibError::ValueKindUnmatch("float", self.kind_str()))
154 }
155 }
156
157 pub fn into_floats(self) -> Result<Vec<f64>, LibError> {
158 self.floats()
159 }
160
161 pub fn into_ident(self) -> Result<String, LibError> {
162 if let Self::Ident(value) = self {
163 Ok(value)
164 } else {
165 Err(LibError::ValueKindUnmatch("ident", self.kind_str()))
166 }
167 }
168
169 pub fn into_string(self) -> Result<String, LibError> {
170 if let Self::String(value) = self {
171 Ok(value)
172 } else {
173 Err(LibError::ValueKindUnmatch("string", self.kind_str()))
174 }
175 }
176
177 pub fn into_literal(self) -> Result<String, LibError> {
178 match self {
179 Self::Ident(value) => Ok(value),
180 Self::String(value) => Ok(value),
181 _ => Err(LibError::ValueKindUnmatch("literal", self.kind_str()))
182 }
183 }
184
185 pub fn into_vector(self) -> Result<Vec<LibValue>, LibError> {
186 if let Self::Vec(value) = self {
187 Ok(value)
188 } else {
189 Err(LibError::ValueKindUnmatch("vector", self.kind_str()))
190 }
191 }
192}
193
194impl LibValue {
195 pub fn is_complex(&self) -> bool {
196 if let Self::Vec(_) = self {
197 true
198 } else {
199 false
200 }
201 }
202}
203
204impl Display for LibValue {
205 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206 match self {
207 Self::Bool(b) => if *b { write!(f, "ture") } else { write!(f, "false") },
208 Self::Float(v) => write!(f, "{}", *v),
209 Self::Ident(v) => write!(f, "{}", v),
210 Self::String(v) => write!(f, "{}", v),
211 Self::Vec(values) => {
212 write!(f, "(")?;
213 for (i, v) in values.iter().enumerate() {
214 if i != 0 {
215 write!(f, ", ")?;
216 }
217 write!(f, "{}", v)?;
218 }
219 write!(f, ")")
220 }
221 }
222 }
223}