rpgmxp_types/
system_words.rs

1use ruby_marshal::FromValue;
2use ruby_marshal::FromValueContext;
3use ruby_marshal::FromValueError;
4use ruby_marshal::IntoValue;
5use ruby_marshal::IntoValueError;
6use ruby_marshal::ObjectValue;
7use ruby_marshal::StringValue;
8use ruby_marshal::SymbolValue;
9use ruby_marshal::Value;
10use ruby_marshal::ValueArena;
11use ruby_marshal::ValueHandle;
12
13const OBJECT_NAME: &[u8] = b"RPG::System::Words";
14
15const STR_FIELD: &[u8] = b"@str";
16const ARMOR3_FIELD: &[u8] = b"@armor3";
17const MDEF_FIELD: &[u8] = b"@mdef";
18const GOLD_FIELD: &[u8] = b"@gold";
19const SP_FIELD: &[u8] = b"@sp";
20const SKILL_FIELD: &[u8] = b"@skill";
21const INT_FIELD: &[u8] = b"@int";
22const ARMOR2_FIELD: &[u8] = b"@armor2";
23const EQUIP_FIELD: &[u8] = b"@equip";
24const HP_FIELD: &[u8] = b"@hp";
25const PDEF_FIELD: &[u8] = b"@pdef";
26const ATTACK_FIELD: &[u8] = b"@attack";
27const AGI_FIELD: &[u8] = b"@agi";
28const ARMOR1_FIELD: &[u8] = b"@armor1";
29const ATK_FIELD: &[u8] = b"@atk";
30const ITEM_FIELD: &[u8] = b"@item";
31const DEX_FIELD: &[u8] = b"@dex";
32const ARMOR4_FIELD: &[u8] = b"@armor4";
33const WEAPON_FIELD: &[u8] = b"@weapon";
34const GUARD_FIELD: &[u8] = b"@guard";
35
36#[derive(Debug, serde::Serialize, serde::Deserialize)]
37pub struct SystemWords {
38    pub str_: String,
39    pub armor3: String,
40    pub mdef: String,
41    pub gold: String,
42    pub sp: String,
43    pub skill: String,
44    pub int: String,
45    pub armor2: String,
46    pub equip: String,
47    pub hp: String,
48    pub pdef: String,
49    pub attack: String,
50    pub agi: String,
51    pub armor1: String,
52    pub atk: String,
53    pub item: String,
54    pub dex: String,
55    pub armor4: String,
56    pub weapon: String,
57    pub guard: String,
58}
59
60impl<'a> FromValue<'a> for SystemWords {
61    fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
62        let object: &ObjectValue = FromValue::from_value(ctx, value)?;
63        let name = object.name();
64        let name: &SymbolValue = ctx.from_value(name.into())?;
65        let name = name.value();
66
67        if name != OBJECT_NAME {
68            return Err(FromValueError::UnexpectedObjectName { name: name.into() });
69        }
70
71        let instance_variables = object.instance_variables();
72
73        let mut str_field = None;
74        let mut armor3_field = None;
75        let mut mdef_field = None;
76        let mut gold_field = None;
77        let mut sp_field = None;
78        let mut skill_field = None;
79        let mut int_field = None;
80        let mut armor2_field = None;
81        let mut equip_field = None;
82        let mut hp_field = None;
83        let mut pdef_field = None;
84        let mut attack_field = None;
85        let mut agi_field = None;
86        let mut armor1_field = None;
87        let mut atk_field = None;
88        let mut item_field = None;
89        let mut dex_field = None;
90        let mut armor4_field = None;
91        let mut weapon_field = None;
92        let mut guard_field = None;
93
94        for (key, value) in instance_variables.iter().copied() {
95            let key: &SymbolValue = ctx.from_value(key.into())?;
96            let key = key.value();
97
98            match key {
99                STR_FIELD => {
100                    if str_field.is_some() {
101                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
102                    }
103
104                    let str_: &StringValue = ctx.from_value(value)?;
105                    let str_ = std::str::from_utf8(str_.value())
106                        .map_err(FromValueError::new_other)?
107                        .to_string();
108                    str_field = Some(str_);
109                }
110                ARMOR3_FIELD => {
111                    if armor3_field.is_some() {
112                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
113                    }
114
115                    let armor3: &StringValue = ctx.from_value(value)?;
116                    let armor3 = std::str::from_utf8(armor3.value())
117                        .map_err(FromValueError::new_other)?
118                        .to_string();
119                    armor3_field = Some(armor3);
120                }
121                MDEF_FIELD => {
122                    if mdef_field.is_some() {
123                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
124                    }
125
126                    let mdef: &StringValue = ctx.from_value(value)?;
127                    let mdef = std::str::from_utf8(mdef.value())
128                        .map_err(FromValueError::new_other)?
129                        .to_string();
130                    mdef_field = Some(mdef);
131                }
132                GOLD_FIELD => {
133                    if gold_field.is_some() {
134                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
135                    }
136
137                    let gold: &StringValue = ctx.from_value(value)?;
138                    let gold = std::str::from_utf8(gold.value())
139                        .map_err(FromValueError::new_other)?
140                        .to_string();
141                    gold_field = Some(gold);
142                }
143                SP_FIELD => {
144                    if sp_field.is_some() {
145                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
146                    }
147
148                    let sp: &StringValue = ctx.from_value(value)?;
149                    let sp = std::str::from_utf8(sp.value())
150                        .map_err(FromValueError::new_other)?
151                        .to_string();
152                    sp_field = Some(sp);
153                }
154                SKILL_FIELD => {
155                    if skill_field.is_some() {
156                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
157                    }
158
159                    let skill: &StringValue = ctx.from_value(value)?;
160                    let skill = std::str::from_utf8(skill.value())
161                        .map_err(FromValueError::new_other)?
162                        .to_string();
163                    skill_field = Some(skill);
164                }
165                INT_FIELD => {
166                    if int_field.is_some() {
167                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
168                    }
169
170                    let int: &StringValue = ctx.from_value(value)?;
171                    let int = std::str::from_utf8(int.value())
172                        .map_err(FromValueError::new_other)?
173                        .to_string();
174                    int_field = Some(int);
175                }
176                ARMOR2_FIELD => {
177                    if armor2_field.is_some() {
178                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
179                    }
180
181                    let armor2: &StringValue = ctx.from_value(value)?;
182                    let armor2 = std::str::from_utf8(armor2.value())
183                        .map_err(FromValueError::new_other)?
184                        .to_string();
185                    armor2_field = Some(armor2);
186                }
187                EQUIP_FIELD => {
188                    if equip_field.is_some() {
189                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
190                    }
191
192                    let equip: &StringValue = ctx.from_value(value)?;
193                    let equip = std::str::from_utf8(equip.value())
194                        .map_err(FromValueError::new_other)?
195                        .to_string();
196                    equip_field = Some(equip);
197                }
198                HP_FIELD => {
199                    if hp_field.is_some() {
200                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
201                    }
202
203                    let hp: &StringValue = ctx.from_value(value)?;
204                    let hp = std::str::from_utf8(hp.value())
205                        .map_err(FromValueError::new_other)?
206                        .to_string();
207                    hp_field = Some(hp);
208                }
209                PDEF_FIELD => {
210                    if pdef_field.is_some() {
211                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
212                    }
213
214                    let pdef: &StringValue = ctx.from_value(value)?;
215                    let pdef = std::str::from_utf8(pdef.value())
216                        .map_err(FromValueError::new_other)?
217                        .to_string();
218                    pdef_field = Some(pdef);
219                }
220                ATTACK_FIELD => {
221                    if attack_field.is_some() {
222                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
223                    }
224
225                    let attack: &StringValue = ctx.from_value(value)?;
226                    let attack = std::str::from_utf8(attack.value())
227                        .map_err(FromValueError::new_other)?
228                        .to_string();
229                    attack_field = Some(attack);
230                }
231                AGI_FIELD => {
232                    if agi_field.is_some() {
233                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
234                    }
235
236                    let agi: &StringValue = ctx.from_value(value)?;
237                    let agi = std::str::from_utf8(agi.value())
238                        .map_err(FromValueError::new_other)?
239                        .to_string();
240                    agi_field = Some(agi);
241                }
242                ARMOR1_FIELD => {
243                    if armor1_field.is_some() {
244                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
245                    }
246
247                    let armor1: &StringValue = ctx.from_value(value)?;
248                    let armor1 = std::str::from_utf8(armor1.value())
249                        .map_err(FromValueError::new_other)?
250                        .to_string();
251                    armor1_field = Some(armor1);
252                }
253                ATK_FIELD => {
254                    if atk_field.is_some() {
255                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
256                    }
257
258                    let atk: &StringValue = ctx.from_value(value)?;
259                    let atk = std::str::from_utf8(atk.value())
260                        .map_err(FromValueError::new_other)?
261                        .to_string();
262                    atk_field = Some(atk);
263                }
264                ITEM_FIELD => {
265                    if item_field.is_some() {
266                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
267                    }
268
269                    let item: &StringValue = ctx.from_value(value)?;
270                    let item = std::str::from_utf8(item.value())
271                        .map_err(FromValueError::new_other)?
272                        .to_string();
273                    item_field = Some(item);
274                }
275                DEX_FIELD => {
276                    if dex_field.is_some() {
277                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
278                    }
279
280                    let dex: &StringValue = ctx.from_value(value)?;
281                    let dex = std::str::from_utf8(dex.value())
282                        .map_err(FromValueError::new_other)?
283                        .to_string();
284                    dex_field = Some(dex);
285                }
286                ARMOR4_FIELD => {
287                    if armor4_field.is_some() {
288                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
289                    }
290
291                    let armor4: &StringValue = ctx.from_value(value)?;
292                    let armor4 = std::str::from_utf8(armor4.value())
293                        .map_err(FromValueError::new_other)?
294                        .to_string();
295                    armor4_field = Some(armor4);
296                }
297                WEAPON_FIELD => {
298                    if weapon_field.is_some() {
299                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
300                    }
301
302                    let weapon: &StringValue = ctx.from_value(value)?;
303                    let weapon = std::str::from_utf8(weapon.value())
304                        .map_err(FromValueError::new_other)?
305                        .to_string();
306                    weapon_field = Some(weapon);
307                }
308                GUARD_FIELD => {
309                    if guard_field.is_some() {
310                        return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
311                    }
312
313                    let guard: &StringValue = ctx.from_value(value)?;
314                    let guard = std::str::from_utf8(guard.value())
315                        .map_err(FromValueError::new_other)?
316                        .to_string();
317                    guard_field = Some(guard);
318                }
319                _ => {
320                    return Err(FromValueError::UnknownInstanceVariable { name: key.into() });
321                }
322            }
323        }
324
325        let str_ = str_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
326            name: STR_FIELD.into(),
327        })?;
328        let armor3 = armor3_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
329            name: ARMOR3_FIELD.into(),
330        })?;
331        let mdef = mdef_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
332            name: MDEF_FIELD.into(),
333        })?;
334        let gold = gold_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
335            name: GOLD_FIELD.into(),
336        })?;
337        let sp = sp_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
338            name: SP_FIELD.into(),
339        })?;
340        let skill = skill_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
341            name: SKILL_FIELD.into(),
342        })?;
343        let int = int_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
344            name: INT_FIELD.into(),
345        })?;
346        let armor2 = armor2_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
347            name: ARMOR2_FIELD.into(),
348        })?;
349        let equip = equip_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
350            name: EQUIP_FIELD.into(),
351        })?;
352        let hp = hp_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
353            name: HP_FIELD.into(),
354        })?;
355        let pdef = pdef_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
356            name: PDEF_FIELD.into(),
357        })?;
358        let attack = attack_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
359            name: ATTACK_FIELD.into(),
360        })?;
361        let agi = agi_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
362            name: AGI_FIELD.into(),
363        })?;
364        let armor1 = armor1_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
365            name: ARMOR1_FIELD.into(),
366        })?;
367        let atk = atk_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
368            name: ATK_FIELD.into(),
369        })?;
370        let item = item_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
371            name: ITEM_FIELD.into(),
372        })?;
373        let dex = dex_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
374            name: DEX_FIELD.into(),
375        })?;
376        let armor4 = armor4_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
377            name: ARMOR4_FIELD.into(),
378        })?;
379        let weapon = weapon_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
380            name: WEAPON_FIELD.into(),
381        })?;
382        let guard = guard_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
383            name: GUARD_FIELD.into(),
384        })?;
385
386        Ok(Self {
387            str_,
388            armor3,
389            mdef,
390            gold,
391            sp,
392            skill,
393            int,
394            armor2,
395            equip,
396            hp,
397            pdef,
398            attack,
399            agi,
400            armor1,
401            atk,
402            item,
403            dex,
404            armor4,
405
406            weapon,
407            guard,
408        })
409    }
410}
411
412impl IntoValue for SystemWords {
413    fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
414        let object_name = arena.create_symbol(OBJECT_NAME.into());
415
416        let str_field_key = arena.create_symbol(STR_FIELD.into());
417        let armor3_field_key = arena.create_symbol(ARMOR3_FIELD.into());
418        let mdef_field_key = arena.create_symbol(MDEF_FIELD.into());
419        let gold_field_key = arena.create_symbol(GOLD_FIELD.into());
420        let sp_field_key = arena.create_symbol(SP_FIELD.into());
421        let skill_field_key = arena.create_symbol(SKILL_FIELD.into());
422        let int_field_key = arena.create_symbol(INT_FIELD.into());
423        let armor2_field_key = arena.create_symbol(ARMOR2_FIELD.into());
424        let equip_field_key = arena.create_symbol(EQUIP_FIELD.into());
425        let hp_field_key = arena.create_symbol(HP_FIELD.into());
426        let pdef_field_key = arena.create_symbol(PDEF_FIELD.into());
427        let attack_field_key = arena.create_symbol(ATTACK_FIELD.into());
428        let agi_field_key = arena.create_symbol(AGI_FIELD.into());
429        let armor1_field_key = arena.create_symbol(ARMOR1_FIELD.into());
430        let atk_field_key = arena.create_symbol(ATK_FIELD.into());
431        let item_field_key = arena.create_symbol(ITEM_FIELD.into());
432        let dex_field_key = arena.create_symbol(DEX_FIELD.into());
433        let armor4_field_key = arena.create_symbol(ARMOR4_FIELD.into());
434        let weapon_field_key = arena.create_symbol(WEAPON_FIELD.into());
435        let guard_field_key = arena.create_symbol(GUARD_FIELD.into());
436
437        let str_field_value = arena.create_string(self.str_.into()).into();
438        let armor3_field_value = arena.create_string(self.armor3.into()).into();
439        let mdef_field_value = arena.create_string(self.mdef.into()).into();
440        let gold_field_value = arena.create_string(self.gold.into()).into();
441        let sp_field_value = arena.create_string(self.sp.into()).into();
442        let skill_field_value = arena.create_string(self.skill.into()).into();
443        let int_field_value = arena.create_string(self.int.into()).into();
444        let armor2_field_value = arena.create_string(self.armor2.into()).into();
445        let equip_field_value = arena.create_string(self.equip.into()).into();
446        let hp_field_value = arena.create_string(self.hp.into()).into();
447        let pdef_field_value = arena.create_string(self.pdef.into()).into();
448        let attack_field_value = arena.create_string(self.attack.into()).into();
449        let agi_field_value = arena.create_string(self.agi.into()).into();
450        let armor1_field_value = arena.create_string(self.armor1.into()).into();
451        let atk_field_value = arena.create_string(self.atk.into()).into();
452        let item_field_value = arena.create_string(self.item.into()).into();
453        let dex_field_value = arena.create_string(self.dex.into()).into();
454        let armor4_field_value = arena.create_string(self.armor4.into()).into();
455        let weapon_field_value = arena.create_string(self.weapon.into()).into();
456        let guard_field_value = arena.create_string(self.guard.into()).into();
457
458        let fields = vec![
459            (str_field_key, str_field_value),
460            (armor3_field_key, armor3_field_value),
461            (mdef_field_key, mdef_field_value),
462            (gold_field_key, gold_field_value),
463            (sp_field_key, sp_field_value),
464            (skill_field_key, skill_field_value),
465            (int_field_key, int_field_value),
466            (armor2_field_key, armor2_field_value),
467            (equip_field_key, equip_field_value),
468            (hp_field_key, hp_field_value),
469            (pdef_field_key, pdef_field_value),
470            (attack_field_key, attack_field_value),
471            (agi_field_key, agi_field_value),
472            (armor1_field_key, armor1_field_value),
473            (atk_field_key, atk_field_value),
474            (item_field_key, item_field_value),
475            (dex_field_key, dex_field_value),
476            (armor4_field_key, armor4_field_value),
477            (weapon_field_key, weapon_field_value),
478            (guard_field_key, guard_field_value),
479        ];
480
481        let object = arena.create_object(object_name, fields);
482
483        Ok(object.into())
484    }
485}