bpx/sd/
value.rs

1// Copyright (c) 2021, BlockProject 3D
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification,
6// are permitted provided that the following conditions are met:
7//
8//     * Redistributions of source code must retain the above copyright notice,
9//       this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above copyright notice,
11//       this list of conditions and the following disclaimer in the documentation
12//       and/or other materials provided with the distribution.
13//     * Neither the name of BlockProject 3D nor the names of its contributors
14//       may be used to endorse or promote products derived from this software
15//       without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29use std::{
30    convert::{From, TryFrom, TryInto},
31    string::String
32};
33
34use crate::{
35    error::Error,
36    sd::{Array, Object},
37    Result
38};
39
40/// Represents a BPXSD value
41#[derive(PartialEq, Clone)]
42pub enum Value
43{
44    /// NULL (0x0)
45    Null,
46
47    /// bool (0x1)
48    Bool(bool),
49
50    /// u8 (0x2)
51    Uint8(u8),
52
53    /// u16 (0x3)
54    Uint16(u16),
55
56    /// u32 (0x4)
57    Uint32(u32),
58
59    /// u64 (0x5)
60    Uint64(u64),
61
62    /// i8 (0x6)
63    Int8(i8),
64
65    /// i16 (0x7)
66    Int16(i16),
67
68    /// i32 (0x8)
69    Int32(i32),
70
71    /// i64 (0x9)
72    Int64(i64),
73
74    /// f32 (0xA)
75    Float(f32),
76
77    /// f64 (0xB)
78    Double(f64),
79
80    /// [String](std::string::String) (0xC)
81    String(String),
82
83    /// [Array](crate::sd::Array) (0xD)
84    Array(Array),
85
86    /// [Object](crate::sd::Object) (0xE)
87    Object(Object)
88}
89
90impl Value
91{
92    /// Gets the variant name of this Value
93    ///
94    /// # Returns
95    ///
96    /// * a static string reference to the variant name
97    pub fn get_type_name(&self) -> &'static str
98    {
99        return match self {
100            Value::Null => "null",
101            Value::Bool(_) => "bool",
102            Value::Uint8(_) => "uint8",
103            Value::Uint16(_) => "uint16",
104            Value::Uint32(_) => "uint32",
105            Value::Uint64(_) => "uint64",
106            Value::Int8(_) => "int8",
107            Value::Int16(_) => "int16",
108            Value::Int32(_) => "int32",
109            Value::Int64(_) => "int64",
110            Value::Float(_) => "float",
111            Value::Double(_) => "double",
112            Value::String(_) => "string",
113            Value::Array(_) => "array",
114            Value::Object(_) => "object"
115        };
116    }
117}
118
119impl From<bool> for Value
120{
121    fn from(v: bool) -> Self
122    {
123        return Value::Bool(v);
124    }
125}
126
127impl From<u8> for Value
128{
129    fn from(v: u8) -> Self
130    {
131        return Value::Uint8(v);
132    }
133}
134
135impl From<u16> for Value
136{
137    fn from(v: u16) -> Self
138    {
139        return Value::Uint16(v);
140    }
141}
142
143impl From<u32> for Value
144{
145    fn from(v: u32) -> Self
146    {
147        return Value::Uint32(v);
148    }
149}
150
151impl From<u64> for Value
152{
153    fn from(v: u64) -> Self
154    {
155        return Value::Uint64(v);
156    }
157}
158
159impl From<i8> for Value
160{
161    fn from(v: i8) -> Self
162    {
163        return Value::Int8(v);
164    }
165}
166
167impl From<i16> for Value
168{
169    fn from(v: i16) -> Self
170    {
171        return Value::Int16(v);
172    }
173}
174
175impl From<i32> for Value
176{
177    fn from(v: i32) -> Self
178    {
179        return Value::Int32(v);
180    }
181}
182
183impl From<i64> for Value
184{
185    fn from(v: i64) -> Self
186    {
187        return Value::Int64(v);
188    }
189}
190
191impl From<f32> for Value
192{
193    fn from(v: f32) -> Self
194    {
195        return Value::Float(v);
196    }
197}
198
199impl From<f64> for Value
200{
201    fn from(v: f64) -> Self
202    {
203        return Value::Double(v);
204    }
205}
206
207impl From<&str> for Value
208{
209    fn from(v: &str) -> Self
210    {
211        return Value::String(String::from(v));
212    }
213}
214
215impl From<String> for Value
216{
217    fn from(v: String) -> Self
218    {
219        return Value::String(v);
220    }
221}
222
223impl From<Array> for Value
224{
225    fn from(v: Array) -> Self
226    {
227        return Value::Array(v);
228    }
229}
230
231impl From<Object> for Value
232{
233    fn from(v: Object) -> Self
234    {
235        return Value::Object(v);
236    }
237}
238
239impl<T: Into<Value>> From<Option<T>> for Value
240{
241    fn from(v: Option<T>) -> Self
242    {
243        if let Some(v) = v {
244            return v.into();
245        }
246        return Value::Null;
247    }
248}
249
250impl<T: Into<Value>> From<Vec<T>> for Value
251{
252    fn from(v: Vec<T>) -> Self
253    {
254        let mut arr = Array::new();
255        for v1 in v {
256            arr.add(v1.into());
257        }
258        return Value::Array(arr);
259    }
260}
261
262impl TryFrom<Value> for bool
263{
264    type Error = Error;
265
266    fn try_from(v: Value) -> Result<Self>
267    {
268        if let Value::Bool(v) = v {
269            return Ok(v);
270        }
271        return Err(Error::TypeError("bool", v.get_type_name()));
272    }
273}
274
275impl TryFrom<Value> for u8
276{
277    type Error = Error;
278
279    fn try_from(v: Value) -> Result<Self>
280    {
281        if let Value::Uint8(v) = v {
282            return Ok(v);
283        }
284        return Err(Error::TypeError("uint8", v.get_type_name()));
285    }
286}
287
288impl TryFrom<Value> for u16
289{
290    type Error = Error;
291
292    fn try_from(v: Value) -> Result<Self>
293    {
294        return match v {
295            Value::Uint16(v) => Ok(v),
296            Value::Uint8(v) => Ok(v as u16),
297            _ => Err(Error::TypeError("uint8 or uint16", v.get_type_name()))
298        };
299    }
300}
301
302impl TryFrom<Value> for u32
303{
304    type Error = Error;
305
306    fn try_from(v: Value) -> Result<Self>
307    {
308        return match v {
309            Value::Uint32(v) => Ok(v),
310            Value::Uint16(v) => Ok(v as u32),
311            Value::Uint8(v) => Ok(v as u32),
312            _ => Err(Error::TypeError("uint8, uint16 or uint32", v.get_type_name()))
313        };
314    }
315}
316
317impl TryFrom<Value> for u64
318{
319    type Error = Error;
320
321    fn try_from(v: Value) -> Result<Self>
322    {
323        return match v {
324            Value::Uint64(v) => Ok(v),
325            Value::Uint32(v) => Ok(v as u64),
326            Value::Uint16(v) => Ok(v as u64),
327            Value::Uint8(v) => Ok(v as u64),
328            _ => Err(Error::TypeError("uint8, uint16, uint32 or uint64", v.get_type_name()))
329        };
330    }
331}
332
333impl TryFrom<Value> for i8
334{
335    type Error = Error;
336
337    fn try_from(v: Value) -> Result<Self>
338    {
339        if let Value::Int8(v) = v {
340            return Ok(v);
341        }
342        return Err(Error::TypeError("int8", v.get_type_name()));
343    }
344}
345
346impl TryFrom<Value> for i16
347{
348    type Error = Error;
349
350    fn try_from(v: Value) -> Result<Self>
351    {
352        return match v {
353            Value::Int16(v) => Ok(v),
354            Value::Int8(v) => Ok(v as i16),
355            _ => Err(Error::TypeError("int8 or int16", v.get_type_name()))
356        };
357    }
358}
359
360impl TryFrom<Value> for i32
361{
362    type Error = Error;
363
364    fn try_from(v: Value) -> Result<Self>
365    {
366        return match v {
367            Value::Int32(v) => Ok(v),
368            Value::Int16(v) => Ok(v as i32),
369            Value::Int8(v) => Ok(v as i32),
370            _ => Err(Error::TypeError("int8, int16 or int32", v.get_type_name()))
371        };
372    }
373}
374
375impl TryFrom<Value> for i64
376{
377    type Error = Error;
378
379    fn try_from(v: Value) -> Result<Self>
380    {
381        return match v {
382            Value::Int64(v) => Ok(v),
383            Value::Int32(v) => Ok(v as i64),
384            Value::Int16(v) => Ok(v as i64),
385            Value::Int8(v) => Ok(v as i64),
386            _ => Err(Error::TypeError("int8, int16, int32 or int64", v.get_type_name()))
387        };
388    }
389}
390
391impl TryFrom<Value> for f32
392{
393    type Error = Error;
394
395    fn try_from(v: Value) -> Result<Self>
396    {
397        if let Value::Float(v) = v {
398            return Ok(v);
399        }
400        return Err(Error::TypeError("float", v.get_type_name()));
401    }
402}
403
404impl TryFrom<Value> for f64
405{
406    type Error = Error;
407
408    fn try_from(v: Value) -> Result<Self>
409    {
410        return match v {
411            Value::Double(v) => Ok(v),
412            Value::Float(v) => Ok(v as f64),
413            _ => Err(Error::TypeError("float or double", v.get_type_name()))
414        };
415    }
416}
417
418impl TryFrom<Value> for String
419{
420    type Error = Error;
421
422    fn try_from(v: Value) -> Result<Self>
423    {
424        if let Value::String(v) = v {
425            return Ok(v);
426        }
427        return Err(Error::TypeError("string", v.get_type_name()));
428    }
429}
430
431impl TryFrom<Value> for Array
432{
433    type Error = Error;
434
435    fn try_from(v: Value) -> Result<Self>
436    {
437        if let Value::Array(v) = v {
438            return Ok(v);
439        }
440        return Err(Error::TypeError("array", v.get_type_name()));
441    }
442}
443
444impl TryFrom<Value> for Object
445{
446    type Error = Error;
447
448    fn try_from(v: Value) -> Result<Self>
449    {
450        if let Value::Object(v) = v {
451            return Ok(v);
452        }
453        return Err(Error::TypeError("object", v.get_type_name()));
454    }
455}
456
457impl TryFrom<&Value> for bool
458{
459    type Error = Error;
460
461    fn try_from(v: &Value) -> Result<Self>
462    {
463        if let Value::Bool(v) = v {
464            return Ok(*v);
465        }
466        return Err(Error::TypeError("bool", v.get_type_name()));
467    }
468}
469
470impl TryFrom<&Value> for u8
471{
472    type Error = Error;
473
474    fn try_from(v: &Value) -> Result<Self>
475    {
476        if let Value::Uint8(v) = v {
477            return Ok(*v);
478        }
479        return Err(Error::TypeError("uint8", v.get_type_name()));
480    }
481}
482
483impl TryFrom<&Value> for u16
484{
485    type Error = Error;
486
487    fn try_from(v: &Value) -> Result<Self>
488    {
489        return match v {
490            Value::Uint16(v) => Ok(*v),
491            Value::Uint8(v) => Ok(*v as u16),
492            _ => Err(Error::TypeError("uint8 or uint16", v.get_type_name()))
493        };
494    }
495}
496
497impl TryFrom<&Value> for u32
498{
499    type Error = Error;
500
501    fn try_from(v: &Value) -> Result<Self>
502    {
503        return match v {
504            Value::Uint32(v) => Ok(*v),
505            Value::Uint16(v) => Ok(*v as u32),
506            Value::Uint8(v) => Ok(*v as u32),
507            _ => Err(Error::TypeError("uint8, uint16 or uint32", v.get_type_name()))
508        };
509    }
510}
511
512impl TryFrom<&Value> for u64
513{
514    type Error = Error;
515
516    fn try_from(v: &Value) -> Result<Self>
517    {
518        return match v {
519            Value::Uint64(v) => Ok(*v),
520            Value::Uint32(v) => Ok(*v as u64),
521            Value::Uint16(v) => Ok(*v as u64),
522            Value::Uint8(v) => Ok(*v as u64),
523            _ => Err(Error::TypeError("uint8, uint16, uint32 or uint64", v.get_type_name()))
524        };
525    }
526}
527
528impl TryFrom<&Value> for i8
529{
530    type Error = Error;
531
532    fn try_from(v: &Value) -> Result<Self>
533    {
534        if let Value::Int8(v) = v {
535            return Ok(*v);
536        }
537        return Err(Error::TypeError("int8", v.get_type_name()));
538    }
539}
540
541impl TryFrom<&Value> for i16
542{
543    type Error = Error;
544
545    fn try_from(v: &Value) -> Result<Self>
546    {
547        return match v {
548            Value::Int16(v) => Ok(*v),
549            Value::Int8(v) => Ok(*v as i16),
550            _ => Err(Error::TypeError("int8 or int16", v.get_type_name()))
551        };
552    }
553}
554
555impl TryFrom<&Value> for i32
556{
557    type Error = Error;
558
559    fn try_from(v: &Value) -> Result<Self>
560    {
561        return match v {
562            Value::Int32(v) => Ok(*v),
563            Value::Int16(v) => Ok(*v as i32),
564            Value::Int8(v) => Ok(*v as i32),
565            _ => Err(Error::TypeError("int8, int16 or int32", v.get_type_name()))
566        };
567    }
568}
569
570impl TryFrom<&Value> for i64
571{
572    type Error = Error;
573
574    fn try_from(v: &Value) -> Result<Self>
575    {
576        return match v {
577            Value::Int64(v) => Ok(*v),
578            Value::Int32(v) => Ok(*v as i64),
579            Value::Int16(v) => Ok(*v as i64),
580            Value::Int8(v) => Ok(*v as i64),
581            _ => Err(Error::TypeError("int8, int16, int32 or int64", v.get_type_name()))
582        };
583    }
584}
585
586impl TryFrom<&Value> for f32
587{
588    type Error = Error;
589
590    fn try_from(v: &Value) -> Result<Self>
591    {
592        if let Value::Float(v) = v {
593            return Ok(*v);
594        }
595        return Err(Error::TypeError("float", v.get_type_name()));
596    }
597}
598
599impl TryFrom<&Value> for f64
600{
601    type Error = Error;
602
603    fn try_from(v: &Value) -> Result<Self>
604    {
605        return match v {
606            Value::Double(v) => Ok(*v),
607            Value::Float(v) => Ok(*v as f64),
608            _ => Err(Error::TypeError("float or double", v.get_type_name()))
609        };
610    }
611}
612
613impl<'a> TryFrom<&'a Value> for &'a str
614{
615    type Error = Error;
616
617    fn try_from(v: &'a Value) -> Result<Self>
618    {
619        if let Value::String(v) = v {
620            return Ok(&v);
621        }
622        return Err(Error::TypeError("string", v.get_type_name()));
623    }
624}
625
626impl<'a> TryFrom<&'a Value> for &'a Array
627{
628    type Error = Error;
629
630    fn try_from(v: &'a Value) -> Result<Self>
631    {
632        if let Value::Array(v) = v {
633            return Ok(&v);
634        }
635        return Err(Error::TypeError("array", v.get_type_name()));
636    }
637}
638
639impl<'a> TryFrom<&'a Value> for &'a Object
640{
641    type Error = Error;
642
643    fn try_from(v: &'a Value) -> Result<Self>
644    {
645        if let Value::Object(v) = v {
646            return Ok(v);
647        }
648        return Err(Error::TypeError("object", v.get_type_name()));
649    }
650}
651
652macro_rules! generate_option_try_from {
653    ($($t:ident)*) => {
654        $(
655            impl TryFrom<Value> for Option<$t>
656            {
657                type Error = Error;
658
659                fn try_from(v: Value) -> Result<Self>
660                {
661                    if let Value::Null = v
662                    {
663                        return Ok(None);
664                    }
665                    let v = v.try_into()?;
666                    return Ok(Some(v));
667                }
668            }
669        )*
670    };
671}
672
673macro_rules! generate_option_try_from_ref {
674    ($($t:ident)*) => {
675        $(
676            impl <'a> TryFrom<&'a Value> for Option<&'a $t>
677            {
678                type Error = Error;
679
680                fn try_from(v: &'a Value) -> Result<Self>
681                {
682                    if let Value::Null = v
683                    {
684                        return Ok(None);
685                    }
686                    let v = v.try_into()?;
687                    return Ok(Some(v));
688                }
689            }
690        )*
691    };
692}
693
694macro_rules! generate_option_try_from_ref_scalar {
695    ($($t:ident)*) => {
696        $(
697            impl <'a> TryFrom<&'a Value> for Option<$t>
698            {
699                type Error = Error;
700
701                fn try_from(v: &'a Value) -> Result<Self>
702                {
703                    if let Value::Null = v
704                    {
705                        return Ok(None);
706                    }
707                    let v = v.try_into()?;
708                    return Ok(Some(v));
709                }
710            }
711        )*
712    };
713}
714
715generate_option_try_from! {
716    u8 u16 u32 u64
717    i8 i16 i32 i64
718    f32 f64 bool
719    String Array Object
720}
721
722generate_option_try_from_ref! {
723    Array Object str
724}
725
726generate_option_try_from_ref_scalar! {
727    u8 u16 u32 u64
728    i8 i16 i32 i64
729    f32 f64 bool
730}