eure_document/parse/
object_key.rs1use crate::{identifier::Identifier, parse::ParseErrorKind, prelude_internal::*};
4use num_bigint::BigInt;
5
6pub trait ParseObjectKey<'doc>: Sized + Eq + core::hash::Hash + Ord {
38 fn from_object_key(key: &'doc ObjectKey) -> Result<Self, ParseErrorKind>;
54
55 fn from_extension_ident(ident: &Identifier) -> Result<Self, ParseErrorKind>;
67}
68
69impl<'doc> ParseObjectKey<'doc> for &'doc ObjectKey {
74 fn from_object_key(key: &'doc ObjectKey) -> Result<Self, ParseErrorKind> {
75 Ok(key)
76 }
77
78 fn from_extension_ident(_ident: &Identifier) -> Result<Self, ParseErrorKind> {
79 Err(ParseErrorKind::TypeMismatch {
81 expected: crate::value::ValueKind::Map,
82 actual: crate::value::ValueKind::Text,
83 })
84 }
85}
86
87impl ParseObjectKey<'_> for ObjectKey {
92 fn from_object_key(key: &ObjectKey) -> Result<Self, ParseErrorKind> {
93 Ok(key.clone())
94 }
95
96 fn from_extension_ident(ident: &Identifier) -> Result<Self, ParseErrorKind> {
97 Ok(ObjectKey::String(ident.as_ref().to_string()))
98 }
99}
100
101impl ParseObjectKey<'_> for bool {
107 fn from_object_key(key: &ObjectKey) -> Result<Self, ParseErrorKind> {
108 match key {
109 ObjectKey::String(s) if s == "true" => Ok(true),
110 ObjectKey::String(s) if s == "false" => Ok(false),
111 _ => Err(ParseErrorKind::TypeMismatch {
112 expected: crate::value::ValueKind::Bool,
113 actual: key_to_value_kind(key),
114 }),
115 }
116 }
117
118 fn from_extension_ident(ident: &Identifier) -> Result<Self, ParseErrorKind> {
119 match ident.as_ref() {
120 "true" => Ok(true),
121 "false" => Ok(false),
122 _ => Err(ParseErrorKind::TypeMismatch {
123 expected: crate::value::ValueKind::Bool,
124 actual: crate::value::ValueKind::Text,
125 }),
126 }
127 }
128}
129
130impl ParseObjectKey<'_> for BigInt {
135 fn from_object_key(key: &ObjectKey) -> Result<Self, ParseErrorKind> {
136 match key {
137 ObjectKey::Number(n) => Ok(n.clone()),
138 _ => Err(ParseErrorKind::TypeMismatch {
139 expected: crate::value::ValueKind::Integer,
140 actual: key_to_value_kind(key),
141 }),
142 }
143 }
144
145 fn from_extension_ident(_ident: &Identifier) -> Result<Self, ParseErrorKind> {
146 Err(ParseErrorKind::TypeMismatch {
148 expected: crate::value::ValueKind::Integer,
149 actual: crate::value::ValueKind::Text,
150 })
151 }
152}
153
154impl ParseObjectKey<'_> for String {
159 fn from_object_key(key: &ObjectKey) -> Result<Self, ParseErrorKind> {
160 match key {
161 ObjectKey::String(s) => Ok(s.clone()),
162 _ => Err(ParseErrorKind::TypeMismatch {
163 expected: crate::value::ValueKind::Text,
164 actual: key_to_value_kind(key),
165 }),
166 }
167 }
168
169 fn from_extension_ident(ident: &Identifier) -> Result<Self, ParseErrorKind> {
170 Ok(ident.as_ref().to_string())
171 }
172}
173
174fn key_to_value_kind(key: &ObjectKey) -> crate::value::ValueKind {
179 match key {
180 ObjectKey::Number(_) => crate::value::ValueKind::Integer,
181 ObjectKey::String(_) => crate::value::ValueKind::Text,
182 ObjectKey::Tuple(_) => crate::value::ValueKind::Tuple,
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189 use crate::value::Tuple;
190
191 #[test]
192 fn test_parse_object_key_borrowed() {
193 let key = ObjectKey::String("test".into());
194 let borrowed: &ObjectKey = ParseObjectKey::from_object_key(&key).unwrap();
195 assert_eq!(borrowed, &key);
196 }
197
198 #[test]
199 fn test_parse_object_key_owned() {
200 let key = ObjectKey::String("test".into());
201 let owned: ObjectKey = ParseObjectKey::from_object_key(&key).unwrap();
202 assert_eq!(owned, key);
203 }
204
205 #[test]
206 fn test_borrowed_key_is_zero_copy() {
207 let key = ObjectKey::String("test".into());
208 let borrowed: &ObjectKey = ParseObjectKey::from_object_key(&key).unwrap();
209 assert!(core::ptr::eq(&key, borrowed));
210 }
211
212 #[test]
213 #[allow(clippy::bool_assert_comparison)]
214 fn test_parse_bool_key() {
215 let key = ObjectKey::String("true".into());
216 let b: bool = ParseObjectKey::from_object_key(&key).unwrap();
217 assert_eq!(b, true);
218
219 let key_false = ObjectKey::String("false".into());
220 let b_false: bool = ParseObjectKey::from_object_key(&key_false).unwrap();
221 assert_eq!(b_false, false);
222 }
223
224 #[test]
225 fn test_parse_bool_key_type_mismatch() {
226 let key = ObjectKey::String("not a bool".into());
227 let result: Result<bool, _> = ParseObjectKey::from_object_key(&key);
228 assert!(result.is_err());
229 }
230
231 #[test]
232 fn test_parse_bigint_key() {
233 let key = ObjectKey::Number(BigInt::from(42));
234 let n: BigInt = ParseObjectKey::from_object_key(&key).unwrap();
235 assert_eq!(n, BigInt::from(42));
236 }
237
238 #[test]
239 fn test_parse_bigint_key_type_mismatch() {
240 let key = ObjectKey::String("not a number".into());
241 let result: Result<BigInt, _> = ParseObjectKey::from_object_key(&key);
242 assert!(result.is_err());
243 }
244
245 #[test]
246 fn test_parse_string_key() {
247 let key = ObjectKey::String("hello".into());
248 let s: String = ParseObjectKey::from_object_key(&key).unwrap();
249 assert_eq!(s, "hello");
250 }
251
252 #[test]
253 fn test_parse_string_key_type_mismatch() {
254 let key = ObjectKey::Number(BigInt::from(123));
255 let result: Result<String, _> = ParseObjectKey::from_object_key(&key);
256 assert!(result.is_err());
257 }
258
259 #[test]
260 fn test_parse_tuple_key() {
261 let key = ObjectKey::Tuple(Tuple(vec![
262 ObjectKey::String("a".into()),
263 ObjectKey::Number(BigInt::from(1)),
264 ]));
265 let owned: ObjectKey = ParseObjectKey::from_object_key(&key).unwrap();
266 assert_eq!(owned, key);
267 }
268}