1use std::collections::HashMap;
4
5#[derive(Debug, Clone, PartialEq)]
7pub enum Value {
8 String(std::string::String),
9 Int(i64),
10 Float(f64),
11 Bool(bool),
12 Null,
13 Array(Vec<Value>),
14 Object(HashMap<std::string::String, Value>),
15 Secret(std::string::String),
17}
18
19impl Value {
20 pub fn as_str(&self) -> Option<&str> {
21 match self {
22 Value::String(s) | Value::Secret(s) => Some(s),
23 _ => None,
24 }
25 }
26
27 pub fn as_int(&self) -> Option<i64> {
28 match self {
29 Value::Int(n) => Some(*n),
30 _ => None,
31 }
32 }
33
34 pub fn as_float(&self) -> Option<f64> {
35 match self {
36 Value::Float(f) => Some(*f),
37 Value::Int(n) => Some(*n as f64),
38 _ => None,
39 }
40 }
41
42 pub fn as_bool(&self) -> Option<bool> {
43 match self {
44 Value::Bool(b) => Some(*b),
45 _ => None,
46 }
47 }
48
49 pub fn as_object(&self) -> Option<&HashMap<std::string::String, Value>> {
50 match self {
51 Value::Object(m) => Some(m),
52 _ => None,
53 }
54 }
55
56 pub fn as_object_mut(&mut self) -> Option<&mut HashMap<std::string::String, Value>> {
57 match self {
58 Value::Object(m) => Some(m),
59 _ => None,
60 }
61 }
62
63 pub fn as_array(&self) -> Option<&Vec<Value>> {
64 match self {
65 Value::Array(a) => Some(a),
66 _ => None,
67 }
68 }
69
70 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
71 match self {
72 Value::Array(a) => Some(a),
73 _ => None,
74 }
75 }
76
77 pub fn as_secret(&self) -> Option<&str> {
78 match self {
79 Value::Secret(s) => Some(s),
80 _ => None,
81 }
82 }
83
84 pub fn is_null(&self) -> bool {
85 matches!(self, Value::Null)
86 }
87
88 pub fn as_number_f64(&self) -> Option<f64> {
89 match self {
90 Value::Int(n) => Some(*n as f64),
91 Value::Float(f) => Some(*f),
92 _ => None,
93 }
94 }
95}
96
97impl std::fmt::Display for Value {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 match self {
100 Value::String(s) | Value::Secret(s) => write!(f, "{}", s),
101 Value::Int(n) => write!(f, "{}", n),
102 Value::Float(fl) => {
103 let s = fl.to_string();
104 if s.contains('.') { write!(f, "{}", s) } else { write!(f, "{}.0", s) }
105 }
106 Value::Bool(b) => write!(f, "{}", b),
107 Value::Null => write!(f, "null"),
108 Value::Array(arr) => {
109 write!(f, "[")?;
110 for (i, item) in arr.iter().enumerate() {
111 if i > 0 { write!(f, ", ")?; }
112 write!(f, "{}", item)?;
113 }
114 write!(f, "]")
115 }
116 Value::Object(_) => write!(f, "[Object]"),
117 }
118 }
119}
120
121impl std::ops::Index<&str> for Value {
122 type Output = Value;
123 fn index(&self, key: &str) -> &Value {
124 match self {
125 Value::Object(map) => map.get(key).expect("key not found"),
126 _ => panic!("not an object"),
127 }
128 }
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub enum Mode {
134 Static,
135 Active,
136}
137
138#[derive(Debug, Clone, PartialEq)]
140pub struct Meta {
141 pub markers: Vec<String>,
142 pub args: Vec<String>,
143 pub type_hint: Option<String>,
144 pub constraints: Option<Constraints>,
145}
146
147#[derive(Debug, Clone, Default, PartialEq)]
149pub struct Constraints {
150 pub min: Option<f64>,
151 pub max: Option<f64>,
152 pub type_name: Option<String>,
153 pub required: bool,
154 pub readonly: bool,
155 pub pattern: Option<String>,
156 pub enum_values: Option<Vec<String>>,
157}
158
159pub type MetaMap = HashMap<String, Meta>;
161
162#[derive(Debug)]
164pub struct ParseResult {
165 pub root: Value,
166 pub mode: Mode,
167 pub locked: bool,
168 pub metadata: HashMap<String, MetaMap>,
171}
172
173#[derive(Debug, Clone, Default)]
175pub struct Options {
176 pub env: Option<HashMap<String, String>>,
177 pub region: Option<String>,
178 pub base_path: Option<String>,
179}