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