wow_alchemy_cdbc/
types.rs

1use std::fmt;
2
3#[cfg(feature = "sqlite")]
4use rusqlite::types::ToSqlOutput;
5
6pub type Key = u32;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct StringRef(pub u32);
10
11impl StringRef {
12    pub fn new(offset: u32) -> Self {
13        Self(offset)
14    }
15
16    pub fn offset(&self) -> u32 {
17        self.0
18    }
19}
20
21#[derive(Debug, Clone)]
22pub enum Value {
23    Int32(i32),
24    UInt32(u32),
25    Float32(f32),
26    String(Option<String>),
27    Bool(bool),
28    UInt8(u8),
29    Int8(i8),
30    UInt16(u16),
31    Int16(i16),
32    Int64(i64),
33    UInt64(u64),
34    Array(Vec<Value>),
35}
36
37impl fmt::Display for Value {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match self {
40            Value::Int32(v) => write!(f, "{v}"),
41            Value::UInt32(v) => write!(f, "{v}"),
42            Value::Float32(v) => write!(f, "{v}"),
43            Value::String(v) => write!(f, "{v:?}"),
44            Value::Bool(v) => write!(f, "{v}"),
45            Value::UInt8(v) => write!(f, "{v}"),
46            Value::Int8(v) => write!(f, "{v}"),
47            Value::UInt16(v) => write!(f, "{v}"),
48            Value::Int16(v) => write!(f, "{v}"),
49            Value::Array(values) => {
50                write!(f, "[")?;
51                for (i, v) in values.iter().enumerate() {
52                    if i > 0 {
53                        write!(f, ", ")?;
54                    }
55                    write!(f, "{v}")?;
56                }
57                write!(f, "]")
58            }
59            Value::Int64(v) => write!(f, "{v}"),
60            Value::UInt64(v) => write!(f, "{v}"),
61        }
62    }
63}
64
65#[cfg(feature = "sqlite")]
66impl From<Value> for ToSqlOutput<'_> {
67    fn from(value: Value) -> Self {
68        match value {
69            Value::String(v) => {
70                if let Some(v) = v {
71                    v.clone().into()
72                } else {
73                    "".into()
74                }
75            }
76            Value::Bool(v) => v.into(),
77            Value::Array(values) => {
78                let parts: Vec<String> = values
79                    .iter()
80                    .map(|i| match i {
81                        Value::String(v) => {
82                            format!(
83                                "\"{}\"",
84                                if let Some(v) = v {
85                                    v.replace("\"", "")
86                                } else {
87                                    "".into()
88                                }
89                            )
90                        }
91                        Value::Bool(v) => (if *v { "true" } else { "false" }).into(),
92                        Value::Array(_) => unreachable!(),
93                        _ => i.to_string(),
94                    })
95                    .collect();
96                format!("[{}]", parts.join(",")).into()
97            }
98            Value::Int32(v) => v.into(),
99            Value::UInt32(v) => v.into(),
100            Value::Float32(v) => v.into(),
101            Value::UInt8(v) => v.into(),
102            Value::Int8(v) => v.into(),
103            Value::UInt16(v) => v.into(),
104            Value::Int16(v) => v.into(),
105            Value::Int64(v) => v.into(),
106            Value::UInt64(v) => v.to_string().into(),
107        }
108    }
109}
110
111pub type Record = Vec<Value>;
112
113/// Represents the type of a field in a DBC record
114#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub enum FieldType {
116    Int32,
117    UInt32,
118    Float32,
119    /// String reference (offset into the string block)
120    String,
121    /// Boolean value (represented as a 32-bit integer)
122    Bool,
123    UInt8,
124    Int8,
125    UInt16,
126    Int16,
127    Int64,
128    UInt64,
129}
130
131impl FieldType {
132    pub fn size(&self) -> usize {
133        match self {
134            FieldType::Int32 => 4,
135            FieldType::UInt32 => 4,
136            FieldType::Float32 => 4,
137            FieldType::String => 4, // String references are 32-bit offsets
138            FieldType::Bool => 4,   // Booleans are represented as 32-bit integers
139            FieldType::UInt8 => 1,
140            FieldType::Int8 => 1,
141            FieldType::UInt16 => 2,
142            FieldType::Int16 => 2,
143            FieldType::Int64 => 8,
144            FieldType::UInt64 => 8,
145        }
146    }
147}