1use std::borrow::Cow;
2use std::fmt::Display;
3use std::hash::Hash;
4use std::str::{self, FromStr};
5use std::mem;
6
7
8use crate::{ParamValue, ParamValueParseError, Value};
9
10#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize))]
16pub enum ValueRef<'a> {
17 String(Cow<'a, str>),
19 Float(f64),
21 Int(i64),
23 Buffer(Cow<'a, [u8]>),
25 #[default]
27 Empty,
28 Boolean(bool),
30 List(Cow<'a, [Value]>),
32}
33
34impl Eq for ValueRef<'_> {}
35
36impl<U: Into<Value>> FromIterator<U> for ValueRef<'static> {
37 fn from_iter<T: IntoIterator<Item = U>>(iter: T) -> Self {
38 let values: Vec<Value> = iter.into_iter().map(|v| v.into()).collect();
39 Self::List(Cow::Owned(values))
40 }
41}
42
43
44impl From<Vec<Value>> for ValueRef<'static> {
45 fn from(value: Vec<Value>) -> Self {
46 Self::List(Cow::Owned(value))
47 }
48}
49
50impl<'a> From<Cow<'a, [Value]>> for ValueRef<'a> {
51 fn from(value: Cow<'a, [Value]>) -> Self {
52 Self::List(value)
53 }
54}
55
56impl From<String> for ValueRef<'_> {
57 fn from(value: String) -> Self {
58 value.parse().unwrap()
59 }
60}
61
62impl<'a> From<&'a str> for ValueRef<'a> {
63 fn from(value: &'a str) -> Self {
64 ValueRef::new(value)
65 }
66}
67
68impl<'a> From<Cow<'a, str>> for ValueRef<'a> {
69 fn from(value: Cow<'a, str>) -> Self {
70 match value {
71 Cow::Borrowed(s) => Self::new(s),
72 Cow::Owned(s) => s.parse().unwrap(),
73 }
74 }
75}
76
77impl PartialEq<String> for ValueRef<'_> {
78 fn eq(&self, other: &String) -> bool {
79 self.as_str() == other.as_str()
80 }
81}
82
83impl PartialEq<str> for ValueRef<'_> {
84 fn eq(&self, other: &str) -> bool {
85 self.as_str() == other
86 }
87}
88
89impl PartialEq<&str> for ValueRef<'_> {
90 fn eq(&self, other: &&str) -> bool {
91 self.as_str() == *other
92 }
93}
94
95impl PartialEq<i64> for ValueRef<'_> {
96 fn eq(&self, other: &i64) -> bool {
97 if let Self::Int(val) = self {
98 val == other
99 } else {
100 false
101 }
102 }
103}
104
105impl PartialEq<f64> for ValueRef<'_> {
106 fn eq(&self, other: &f64) -> bool {
107 if let Self::Float(val) = self {
108 val == other
109 } else {
110 false
111 }
112 }
113}
114
115impl PartialEq<bool> for ValueRef<'_> {
116 fn eq(&self, other: &bool) -> bool {
117 if let Self::Boolean(val) = self {
118 val == other
119 } else {
120 false
121 }
122 }
123}
124
125impl FromStr for ValueRef<'_> {
126 type Err = ParamValueParseError;
127
128 fn from_str(s: &str) -> Result<Self, Self::Err> {
129 if s.is_empty() {
130 return Ok(Self::Empty);
131 }
132 if let Ok(value) = s.parse() {
133 Ok(Self::Int(value))
134 } else if let Ok(value) = s.parse() {
135 Ok(Self::Float(value))
136 } else if let Ok(value) = s.parse() {
137 Ok(Self::Boolean(value))
138 } else {
139 Ok(Self::String(Cow::Owned(s.to_string())))
140 }
141 }
142}
143
144impl Display for ValueRef<'_> {
145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146 match self {
147 Self::String(v) => f.write_str(v),
148 Self::Float(v) => v.fmt(f),
149 Self::Int(v) => v.fmt(f),
150 Self::Buffer(v) => f.write_str(&String::from_utf8_lossy(v)),
151 Self::Empty => f.write_str(""),
152 Self::Boolean(v) => v.fmt(f),
153 Self::List(v) => {
154 f.write_str("[ ")?;
155 if let Some(vi) = v.first() {
156 vi.fmt(f)?;
157 }
158 for vi in v.iter().skip(1) {
159 f.write_str(", ")?;
160 vi.fmt(f)?;
161 }
162 f.write_str(" ]")
163 }
164 }
165 }
166}
167
168impl<'a> ValueRef<'a> {
169 pub fn new(s: &'a str) -> Self {
173 if s.is_empty() {
174 return Self::Empty;
175 }
176 if let Ok(value) = s.parse::<i64>() {
177 Self::Int(value)
178 } else if let Ok(value) = s.parse::<f64>() {
179 Self::Float(value)
180 } else if let Ok(value) = s.parse() {
181 Self::Boolean(value)
182 } else {
183 Self::String(Cow::Borrowed(s))
184 }
185 }
186
187 pub const fn wrap(s: &'a str) -> Self {
189 Self::String(Cow::Borrowed(s))
190 }
191
192 fn is_empty(&self) -> bool {
193 matches!(self, Self::Empty)
194 }
195
196 fn is_i64(&self) -> bool {
197 matches!(self, Self::Int(_))
198 }
199
200 fn is_f64(&self) -> bool {
201 matches!(self, Self::Float(_))
202 }
203
204 fn is_buffer(&self) -> bool {
205 matches!(self, Self::Buffer(_))
206 }
207
208 fn is_str(&self) -> bool {
209 matches!(self, Self::String(_))
210 }
211
212 fn is_list(&self) -> bool {
213 matches!(self, Self::List(_))
214 }
215
216 fn to_bool(&self) -> Result<bool, ParamValueParseError> {
217 if let Self::Boolean(val) = self {
218 Ok(*val)
219 } else if self.is_numeric() {
220 Ok(self.to_i64()? != 0)
221 } else if let Self::Empty = self {
222 Ok(false)
223 } else if let Ok(v) = self.parse() {
224 Ok(v)
225 } else {
226 Err(ParamValueParseError::FailedToExtractInt(Some(
227 self.to_string(),
228 )))
229 }
230 }
231
232 pub fn coerce_bool(&mut self) -> Result<(), ParamValueParseError> {
234 let value = self.to_bool()?;
235 *self = Self::Boolean(value);
236 Ok(())
237 }
238
239 pub fn coerce_f64(&mut self) -> Result<(), ParamValueParseError> {
241 let value = self.to_f64()?;
242 *self = Self::Float(value);
243 Ok(())
244 }
245
246 pub fn coerce_i64(&mut self) -> Result<(), ParamValueParseError> {
248 let value = self.to_i64()?;
249 *self = Self::Int(value);
250 Ok(())
251 }
252
253 pub fn coerce_str(&mut self) -> Result<(), ParamValueParseError> {
255 if self.is_str() {
256 } else {
257 let value = self.to_string();
258 *self = Self::String(Cow::Owned(value));
259 }
260 Ok(())
261 }
262
263 pub fn coerce_empty(&mut self) {
265 *self = Self::Empty;
266 }
267
268 pub fn coerce_buffer(&mut self) -> Result<(), ParamValueParseError> {
270 if self.is_buffer() {
271 Ok(())
272 } else {
273 let buffer = Cow::Owned(self.to_buffer()?.to_vec());
274 *self = Self::Buffer(buffer);
275 Ok(())
276 }
277 }
278
279 pub fn coerce_list(&mut self) -> Result<(), ParamValueParseError> {
281 if !self.is_list() {
282 let dup = match self {
283 Self::Boolean(v) => Value::Boolean(*v),
284 Self::Empty => Value::Empty,
285 Self::Float(v) => Value::Float(*v),
286 Self::Int(v) => Value::Int(*v),
287 Self::Buffer(v) => Value::Buffer(v.to_vec().into()),
288 Self::String(v) => Value::String(v.to_string()),
289 Self::List(_) => unimplemented!(),
290 };
291 *self = Self::List(Cow::Owned([dup].into()));
292 }
293 Ok(())
294 }
295
296 fn parse<T: FromStr>(&self) -> Result<T, T::Err> {
297 match self {
298 Self::String(s) => s.parse(),
299 Self::Float(v) => v.to_string().parse(),
300 Self::Int(i) => i.to_string().parse(),
301 Self::Buffer(b) => String::from_utf8_lossy(b).parse(),
302 Self::Empty => "".parse(),
303 Self::Boolean(v) => v.to_string().parse(),
304 Self::List(_) => self.to_string().parse(),
305 }
306 }
307
308 fn to_f64(&self) -> Result<f64, ParamValueParseError> {
309 if let Self::Float(val) = self {
310 return Ok(*val);
311 } else if let Self::Int(val) = self {
312 return Ok(*val as f64);
313 } else if let Self::String(val) = self {
314 if let Ok(v) = val.parse() {
315 return Ok(v);
316 }
317 }
318 Err(ParamValueParseError::FailedToExtractFloat(Some(
319 self.to_string(),
320 )))
321 }
322
323 fn to_i64(&self) -> Result<i64, ParamValueParseError> {
324 if let Self::Int(val) = self {
325 return Ok(*val);
326 } else if let Self::Float(val) = self {
327 return Ok(*val as i64);
328 } else if let Self::String(val) = self {
329 if let Ok(v) = val.parse() {
330 return Ok(v);
331 }
332 }
333 Err(ParamValueParseError::FailedToExtractInt(Some(
334 self.to_string(),
335 )))
336 }
337
338 fn to_str(&self) -> Cow<'_, str> {
339 if let Self::String(val) = self {
340 Cow::Borrowed(val)
341 } else {
342 Cow::Owned(self.to_string())
343 }
344 }
345
346 fn to_buffer(&self) -> Result<Cow<'_, [u8]>, ParamValueParseError> {
347 if let Self::Buffer(val) = self {
348 match val {
349 Cow::Borrowed(v) => Ok(Cow::Borrowed(*v)),
350 Cow::Owned(v) => Ok(Cow::Borrowed(v)),
351 }
352 } else if let Self::String(val) = self {
353 Ok(Cow::Borrowed(val.as_bytes()))
354 } else {
355 Err(ParamValueParseError::FailedToExtractBuffer)
356 }
357 }
358}
359
360impl ParamValue for ValueRef<'_> {
361 fn is_empty(&self) -> bool {
362 self.is_empty()
363 }
364
365 fn is_i64(&self) -> bool {
366 self.is_i64()
367 }
368
369 fn is_f64(&self) -> bool {
370 self.is_f64()
371 }
372
373 fn is_buffer(&self) -> bool {
374 self.is_buffer()
375 }
376
377 fn is_str(&self) -> bool {
378 self.is_str()
379 }
380
381 fn is_boolean(&self) -> bool {
382 matches!(self, Self::Boolean(_))
383 }
384
385 fn to_bool(&self) -> Result<bool, ParamValueParseError> {
386 self.to_bool()
387 }
388
389 fn to_f64(&self) -> Result<f64, ParamValueParseError> {
390 self.to_f64()
391 }
392
393 fn to_i64(&self) -> Result<i64, ParamValueParseError> {
394 self.to_i64()
395 }
396
397 fn to_str(&self) -> Cow<'_, str> {
398 self.to_str()
399 }
400
401 fn to_buffer(&self) -> Result<Cow<'_, [u8]>, ParamValueParseError> {
402 self.to_buffer()
403 }
404
405 fn parse<T: FromStr>(&self) -> Result<T, T::Err> {
406 self.parse()
407 }
408
409 fn as_bytes(&self) -> Cow<'_, [u8]> {
410 match self {
411 Self::String(v) => Cow::Borrowed(v.as_bytes()),
412 Self::Buffer(v) => Cow::Borrowed(v.as_ref()),
413 Self::Float(v) => Cow::Owned(v.to_string().into_bytes()),
414 Self::Int(v) => Cow::Owned(v.to_string().into_bytes()),
415 Self::Empty => Cow::Borrowed(b""),
416 Self::Boolean(v) => Cow::Owned(v.to_string().into_bytes()),
417 Self::List(_) => Cow::Owned(self.to_string().into_bytes()),
418 }
419 }
420
421 fn as_ref(&self) -> ValueRef<'_> {
422 self.clone()
423 }
424
425 fn data_len(&self) -> usize {
426 match self {
427 Self::String(v) => v.len(),
428 Self::Buffer(v) => v.len(),
429 Self::Float(_) => 8,
430 Self::Int(_) => 8,
431 Self::Empty => 0,
432 Self::Boolean(_) => mem::size_of::<bool>(),
433 Self::List(v) => v.iter().map(|vi| vi.data_len()).sum(),
434 }
435 }
436
437 fn is_list(&self) -> bool {
438 self.is_list()
439 }
440
441 fn as_slice(&self) -> Cow<'_, [Value]> {
442 match self {
443 Self::List(v) => Cow::Borrowed(v),
444 _ => {
445 let dup = match self {
446 Self::Boolean(v) => Value::Boolean(*v),
447 Self::Empty => Value::Empty,
448 Self::Float(v) => Value::Float(*v),
449 Self::Int(v) => Value::Int(*v),
450 Self::Buffer(v) => Value::Buffer(v.to_vec().into()),
451 Self::String(v) => Value::String(v.to_string()),
452 Self::List(_) => unimplemented!(),
453 };
454 Cow::Owned([dup].into())
455 }
456 }
457 }
458}
459
460impl<'a> From<&'a Value> for ValueRef<'a> {
461 fn from(value: &'a Value) -> Self {
462 match value {
463 Value::String(s) => Self::String(Cow::Borrowed(s)),
464 Value::Float(v) => Self::Float(*v),
465 Value::Int(v) => Self::Int(*v),
466 Value::Buffer(v) => Self::Buffer(Cow::Borrowed(v)),
467 Value::Empty => Self::Empty,
468 Value::Boolean(v) => Self::Boolean(*v),
469 Value::List(v) => Self::List(Cow::Borrowed(v)),
470 }
471 }
472}
473
474impl PartialEq<Value> for ValueRef<'_> {
475 fn eq(&self, other: &Value) -> bool {
476 *self == other.as_ref()
477 }
478}
479
480impl<'a> PartialEq<ValueRef<'a>> for Value {
481 fn eq(&self, other: &ValueRef<'a>) -> bool {
482 self.as_ref() == *other
483 }
484}
485
486impl<'a> From<ValueRef<'a>> for Value {
487 fn from(value: ValueRef<'a>) -> Self {
488 match value {
489 ValueRef::String(s) => match s {
490 Cow::Borrowed(s) => Self::String(s.to_string()),
491 Cow::Owned(s) => Self::String(s),
492 },
493 ValueRef::Float(v) => Self::Float(v),
494 ValueRef::Int(v) => Self::Int(v),
495 ValueRef::Buffer(v) => Self::Buffer(v.to_vec().into_boxed_slice()),
496 ValueRef::Empty => Self::Empty,
497 ValueRef::Boolean(v) => Self::Boolean(v),
498 ValueRef::List(v) => {
499 let mut ve = Vec::with_capacity(v.len());
500 for vi in v.iter() {
501 ve.push(vi.clone())
502 }
503 Self::List(ve.into_boxed_slice())
504 }
505 }
506 }
507}
508
509impl Hash for ValueRef<'_> {
510 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
511 core::mem::discriminant(self).hash(state);
512 match self {
513 Self::String(s) => s.hash(state),
514 Self::Float(v) => v.to_bits().hash(state),
515 Self::Int(v) => (*v).hash(state),
516 Self::Buffer(v) => v.hash(state),
517 Self::Empty => 0u8.hash(state),
518 Self::Boolean(v) => (*v).hash(state),
519 Self::List(v) => v.iter().for_each(|vi| vi.hash(state)),
520 }
521 }
522}
523
524macro_rules! param_value_ref_int {
525 ($val:ty) => {
526 impl<'a> From<$val> for ValueRef<'a> {
527 fn from(value: $val) -> Self {
528 Self::Int(value as i64)
529 }
530 }
531
532 impl<'a> From<&$val> for ValueRef<'a> {
533 fn from(value: &$val) -> Self {
534 Self::Int(*value as i64)
535 }
536 }
537
538 impl<'a> From<Option<$val>> for ValueRef<'a> {
539 fn from(value: Option<$val>) -> Self {
540 if let Some(v) = value {
541 Self::Int(v as i64)
542 } else {
543 Self::Empty
544 }
545 }
546 }
547 };
548}
549
550macro_rules! param_value_ref_float {
551 ($val:ty) => {
552 impl<'a> From<$val> for ValueRef<'a> {
553 fn from(value: $val) -> Self {
554 Self::Float(value as f64)
555 }
556 }
557
558 impl<'a> From<&$val> for ValueRef<'a> {
559 fn from(value: &$val) -> Self {
560 Self::Float(*value as f64)
561 }
562 }
563
564 impl<'a> From<Option<$val>> for ValueRef<'a> {
565 fn from(value: Option<$val>) -> Self {
566 if let Some(v) = value {
567 Self::Float(v as f64)
568 } else {
569 Self::Empty
570 }
571 }
572 }
573 };
574}
575
576impl From<ValueRef<'_>> for f32 {
577 fn from(value: ValueRef<'_>) -> Self {
578 value.to_f32().unwrap()
579 }
580}
581
582impl From<ValueRef<'_>> for f64 {
583 fn from(value: ValueRef<'_>) -> Self {
584 value.to_f64().unwrap()
585 }
586}
587
588impl From<ValueRef<'_>> for i32 {
589 fn from(value: ValueRef<'_>) -> Self {
590 value.to_i32().unwrap()
591 }
592}
593
594impl From<ValueRef<'_>> for i64 {
595 fn from(value: ValueRef<'_>) -> Self {
596 value.to_i64().unwrap()
597 }
598}
599
600impl From<bool> for Value {
601 fn from(value: bool) -> Self {
602 Self::Boolean(value)
603 }
604}
605
606impl From<bool> for ValueRef<'_> {
607 fn from(value: bool) -> Self {
608 Self::Boolean(value)
609 }
610}
611
612param_value_ref_int!(i8);
613param_value_ref_int!(i16);
614param_value_ref_int!(i32);
615param_value_ref_int!(i64);
616
617param_value_ref_int!(u8);
618param_value_ref_int!(u16);
619param_value_ref_int!(u32);
620param_value_ref_int!(u64);
621param_value_ref_int!(usize);
622
623param_value_ref_float!(f32);
624param_value_ref_float!(f64);