1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::{collections::HashMap, ffi::OsString};

/// Represents a generic rust value
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    Primitive(Primitive),
    Struct(Struct),
    Enum(Enum),
    Map(HashMap<HashableValue, Value>),
    List(Vec<Value>),
    None,
}

/// Represents an enum with a given variant
/// And fields depending on that variant
#[derive(Clone, Debug, PartialEq)]
pub struct Enum {
    pub name: String,
    pub variant: String,
    pub fields: Fields,
}

/// Represents a struct with fields
#[derive(Clone, Debug, PartialEq)]
pub struct Struct {
    pub name: String,
    pub fields: Fields,
}

/// Fields of a struct or an enum that are either named, unnamed or not defined (Unit enums/structs)
#[derive(Clone, Debug, PartialEq)]
pub enum Fields {
    Named(HashMap<String, Value>),
    Unnamed(Vec<Value>),
    Unit,
}

/// A rust primitive value
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub enum Primitive {
    Integer(Integer),
    Float(Float),
    String(String),
    OsString(OsString),
    Char(char),
    Bool(bool),
}

/// A primitive integer value
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum Integer {
    USize(usize),
    ISize(isize),
    U8(u8),
    I8(i8),
    U16(u16),
    I16(i16),
    U32(u32),
    I32(i32),
    U64(u64),
    I64(i64),
    U128(u128),
    I128(i128),
}

/// A primitive float value
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub enum Float {
    F32(f32),
    F64(f64),
}

/// A value that can be used as a key inside a hash map
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum HashableValue {
    Primitive(HashablePrimitive),
    List(Vec<HashableValue>),
    None,
}

/// A primitive that can be used as a hash map key
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum HashablePrimitive {
    Integer(Integer),
    String(String),
    OsString(OsString),
    Char(char),
    Bool(bool),
}

impl ToString for HashablePrimitive {
    fn to_string(&self) -> String {
        match self {
            HashablePrimitive::Integer(i) => i.to_string(),
            HashablePrimitive::String(s) => s.to_owned(),
            HashablePrimitive::Char(c) => c.to_string(),
            HashablePrimitive::Bool(b) => b.to_string(),
            HashablePrimitive::OsString(o) => o.to_string_lossy().into_owned(),
        }
    }
}

impl ToString for Integer {
    fn to_string(&self) -> String {
        match self {
            Integer::USize(n) => n.to_string(),
            Integer::ISize(n) => n.to_string(),
            Integer::U8(n) => n.to_string(),
            Integer::I8(n) => n.to_string(),
            Integer::U16(n) => n.to_string(),
            Integer::I16(n) => n.to_string(),
            Integer::U32(n) => n.to_string(),
            Integer::I32(n) => n.to_string(),
            Integer::U64(n) => n.to_string(),
            Integer::I64(n) => n.to_string(),
            Integer::U128(n) => n.to_string(),
            Integer::I128(n) => n.to_string(),
        }
    }
}

impl ToString for Float {
    fn to_string(&self) -> String {
        match self {
            Float::F32(f) => f.to_string(),
            Float::F64(f) => f.to_string(),
        }
    }
}