1use super::{GffLabel, GffLocalizedString, GffStruct, GffValue};
15use rakata_core::ResRef;
16
17pub fn upsert_field(structure: &mut GffStruct, label: GffLabel, value: GffValue) {
23 if let Some(field) = structure
24 .fields
25 .iter_mut()
26 .find(|field| field.label == label)
27 {
28 field.value = value;
29 } else {
30 structure.push_field(label, value);
31 }
32}
33
34pub fn get_string(structure: &GffStruct, label: &str) -> Option<String> {
36 match structure.field(label) {
37 Some(GffValue::String(value)) => Some(value.clone()),
38 _ => None,
39 }
40}
41
42pub fn get_resref(structure: &GffStruct, label: &str) -> Option<ResRef> {
44 match structure.field(label) {
45 Some(GffValue::ResRef(value)) => Some(*value),
46 _ => None,
47 }
48}
49
50pub fn get_locstring<'a>(structure: &'a GffStruct, label: &str) -> Option<&'a GffLocalizedString> {
52 match structure.field(label) {
53 Some(GffValue::LocalizedString(value)) => Some(value),
54 _ => None,
55 }
56}
57
58pub fn get_i8(structure: &GffStruct, label: &str) -> Option<i8> {
60 match structure.field(label) {
61 Some(GffValue::Int8(value)) => Some(*value),
62 Some(GffValue::UInt8(value)) => i8::try_from(*value).ok(),
63 Some(GffValue::Int16(value)) => i8::try_from(*value).ok(),
64 Some(GffValue::UInt16(value)) => i8::try_from(*value).ok(),
65 Some(GffValue::Int32(value)) => i8::try_from(*value).ok(),
66 Some(GffValue::UInt32(value)) => i8::try_from(*value).ok(),
67 _ => None,
68 }
69}
70
71pub fn get_i16(structure: &GffStruct, label: &str) -> Option<i16> {
73 match structure.field(label) {
74 Some(GffValue::Int16(value)) => Some(*value),
75 Some(GffValue::UInt16(value)) => i16::try_from(*value).ok(),
76 Some(GffValue::Int8(value)) => Some(i16::from(*value)),
77 Some(GffValue::UInt8(value)) => Some(i16::from(*value)),
78 Some(GffValue::Int32(value)) => i16::try_from(*value).ok(),
79 Some(GffValue::UInt32(value)) => i16::try_from(*value).ok(),
80 _ => None,
81 }
82}
83
84pub fn get_i32(structure: &GffStruct, label: &str) -> Option<i32> {
86 match structure.field(label) {
87 Some(GffValue::Int32(value)) => Some(*value),
88 Some(GffValue::UInt32(value)) => i32::try_from(*value).ok(),
89 Some(GffValue::Int16(value)) => Some(i32::from(*value)),
90 Some(GffValue::UInt16(value)) => Some(i32::from(*value)),
91 Some(GffValue::Int8(value)) => Some(i32::from(*value)),
92 Some(GffValue::UInt8(value)) => Some(i32::from(*value)),
93 _ => None,
94 }
95}
96
97pub fn get_u8(structure: &GffStruct, label: &str) -> Option<u8> {
99 match structure.field(label) {
100 Some(GffValue::UInt8(value)) => Some(*value),
101 Some(GffValue::Int8(value)) => u8::try_from(*value).ok(),
102 Some(GffValue::UInt16(value)) => u8::try_from(*value).ok(),
103 Some(GffValue::Int16(value)) => u8::try_from(*value).ok(),
104 Some(GffValue::UInt32(value)) => u8::try_from(*value).ok(),
105 Some(GffValue::Int32(value)) => u8::try_from(*value).ok(),
106 _ => None,
107 }
108}
109
110pub fn get_u16(structure: &GffStruct, label: &str) -> Option<u16> {
112 match structure.field(label) {
113 Some(GffValue::UInt16(value)) => Some(*value),
114 Some(GffValue::Int16(value)) => u16::try_from(*value).ok(),
115 Some(GffValue::UInt8(value)) => Some(u16::from(*value)),
116 Some(GffValue::Int8(value)) => u16::try_from(*value).ok(),
117 Some(GffValue::UInt32(value)) => u16::try_from(*value).ok(),
118 Some(GffValue::Int32(value)) => u16::try_from(*value).ok(),
119 _ => None,
120 }
121}
122
123pub fn get_u32(structure: &GffStruct, label: &str) -> Option<u32> {
125 match structure.field(label) {
126 Some(GffValue::UInt32(value)) => Some(*value),
127 Some(GffValue::Int32(value)) => u32::try_from(*value).ok(),
128 Some(GffValue::UInt16(value)) => Some(u32::from(*value)),
129 Some(GffValue::UInt8(value)) => Some(u32::from(*value)),
130 _ => None,
131 }
132}
133
134pub fn get_u32_extended_signed(structure: &GffStruct, label: &str) -> Option<u32> {
136 match structure.field(label) {
137 Some(GffValue::UInt32(value)) => Some(*value),
138 Some(GffValue::Int32(value)) => u32::try_from(*value).ok(),
139 Some(GffValue::UInt16(value)) => Some(u32::from(*value)),
140 Some(GffValue::Int16(value)) => u32::try_from(*value).ok(),
141 Some(GffValue::UInt8(value)) => Some(u32::from(*value)),
142 Some(GffValue::Int8(value)) => u32::try_from(*value).ok(),
143 _ => None,
144 }
145}
146
147pub fn get_f32(structure: &GffStruct, label: &str) -> Option<f32> {
149 match structure.field(label) {
150 Some(GffValue::Single(value)) => Some(*value),
151 #[allow(clippy::cast_possible_truncation, clippy::as_conversions)]
153 Some(GffValue::Double(value)) => Some(*value as f32),
154 _ => None,
155 }
156}
157
158pub fn get_binary<'a>(structure: &'a GffStruct, label: &str) -> Option<&'a [u8]> {
163 match structure.field(label) {
164 Some(GffValue::Binary(bytes)) => Some(bytes),
165 _ => None,
166 }
167}
168
169pub fn get_u64(structure: &GffStruct, label: &str) -> Option<u64> {
171 match structure.field(label) {
172 Some(GffValue::UInt64(value)) => Some(*value),
173 Some(GffValue::UInt32(value)) => Some(u64::from(*value)),
174 Some(GffValue::Int64(value)) => u64::try_from(*value).ok(),
175 Some(GffValue::Int32(value)) => u64::try_from(*value).ok(),
176 Some(GffValue::UInt16(value)) => Some(u64::from(*value)),
177 Some(GffValue::UInt8(value)) => Some(u64::from(*value)),
178 _ => None,
179 }
180}
181
182pub fn get_bool(structure: &GffStruct, label: &str) -> Option<bool> {
184 match structure.field(label) {
185 Some(GffValue::UInt8(value)) => Some(*value != 0),
186 Some(GffValue::Int8(value)) => Some(*value != 0),
187 Some(GffValue::UInt16(value)) => Some(*value != 0),
188 Some(GffValue::Int16(value)) => Some(*value != 0),
189 Some(GffValue::UInt32(value)) => Some(*value != 0),
190 Some(GffValue::Int32(value)) => Some(*value != 0),
191 _ => None,
192 }
193}