gistools/parsers/wkt/
object.rs1use super::clean_string;
2use alloc::{
3 string::{String, ToString},
4 vec,
5 vec::Vec,
6};
7
8#[derive(Debug, Clone, PartialEq)]
10pub enum WKTValue {
11 String(String),
13 Array(Vec<WKTValue>),
15}
16impl WKTValue {
17 #[allow(clippy::inherent_to_string)]
19 pub fn to_string(&self) -> String {
20 match self {
21 WKTValue::String(s) => s.clone(),
22 WKTValue::Array(_) => "".into(),
23 }
24 }
25 pub fn to_float(&self) -> f64 {
27 match self {
28 WKTValue::String(s) => s.parse().unwrap_or_default(),
29 WKTValue::Array(_) => 0.,
30 }
31 }
32 pub fn to_arr(&self) -> Option<&Vec<WKTValue>> {
34 match self {
35 WKTValue::Array(arr) => Some(arr),
36 WKTValue::String(_) => None,
37 }
38 }
39 pub fn is_array(&self) -> bool {
41 matches!(self, WKTValue::Array(_))
42 }
43}
44pub type WKTObject = Vec<WKTValue>;
46
47pub trait WKTParser: Default {
49 fn from_wkt(wkt: &WKTValue) -> Self;
51}
52
53pub fn parse_wkt_object(wkt_str: &str) -> WKTValue {
55 let wkt_str = clean_string(wkt_str);
56 let mut res: WKTObject = vec![];
57 _parse_wkt_object(wkt_str, &mut res);
58
59 WKTValue::Array(res)
61}
62
63fn _parse_wkt_object(wkt_str: String, res: &mut WKTObject) -> String {
72 let mut wkt_str = wkt_str;
73
74 while !wkt_str.is_empty() {
75 let comma_index = wkt_str.find(',').unwrap_or(usize::MAX);
77 let start_bracket_index = wkt_str.find('[').unwrap_or(usize::MAX);
78 let end_bracket_index = wkt_str.find(']').unwrap_or(usize::MAX);
79
80 if comma_index < start_bracket_index.min(end_bracket_index) {
81 let key = wkt_str[..comma_index].to_string();
83 if !key.is_empty() {
84 res.push(WKTValue::String(clean_string(&key)));
85 }
86 wkt_str = wkt_str[comma_index + 1..].to_string();
87 } else if start_bracket_index < end_bracket_index {
88 let key = wkt_str[..start_bracket_index].to_string();
90 let mut arr = WKTObject::new();
91 wkt_str = _parse_wkt_object(wkt_str[start_bracket_index + 1..].to_string(), &mut arr);
92 res.push(WKTValue::String(clean_string(&key)));
93 res.push(WKTValue::Array(arr));
94 } else {
95 if end_bracket_index > 0 {
97 let key = clean_string(&wkt_str[..end_bracket_index]);
98 if !key.is_empty() {
99 res.push(WKTValue::String(key));
100 }
101 wkt_str = wkt_str[end_bracket_index + 1..].to_string();
102 } else {
103 wkt_str = wkt_str[1..].to_string();
105 }
106 return wkt_str;
107 }
108 }
109
110 wkt_str
112}