rpgmxp_types/
common_event.rs1use crate::EventCommand;
2use ruby_marshal::FromValue;
3use ruby_marshal::FromValueContext;
4use ruby_marshal::FromValueError;
5use ruby_marshal::IntoValue;
6use ruby_marshal::IntoValueError;
7use ruby_marshal::ObjectValue;
8use ruby_marshal::StringValue;
9use ruby_marshal::SymbolValue;
10use ruby_marshal::Value;
11use ruby_marshal::ValueArena;
12use ruby_marshal::ValueHandle;
13
14const OBJECT_NAME: &[u8] = b"RPG::CommonEvent";
15
16const NAME_FIELD: &[u8] = b"@name";
17const LIST_FIELD: &[u8] = b"@list";
18const TRIGGER_FIELD: &[u8] = b"@trigger";
19const SWITCH_ID_FIELD: &[u8] = b"@switch_id";
20const ID_FIELD: &[u8] = b"@id";
21
22#[derive(Debug, serde::Serialize, serde::Deserialize)]
23pub struct CommonEvent {
24 pub name: String,
25 pub list: Vec<EventCommand>,
26 pub trigger: i32,
27 pub switch_id: i32,
28 pub id: i32,
29}
30
31impl<'a> FromValue<'a> for CommonEvent {
32 fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
33 let object: &ObjectValue = FromValue::from_value(ctx, value)?;
34 let name = object.name();
35 let name: &SymbolValue = ctx.from_value(name.into())?;
36 let name = name.value();
37 if name != OBJECT_NAME {
38 return Err(FromValueError::UnexpectedObjectName { name: name.into() });
39 }
40
41 let instance_variables = object.instance_variables();
42
43 let mut name_field = None;
44 let mut list_field = None;
45 let mut trigger_field = None;
46 let mut switch_id_field = None;
47 let mut id_field = None;
48
49 for (key, value) in instance_variables.iter().copied() {
50 let key: &SymbolValue = ctx.from_value(key.into())?;
51 let key = key.value();
52
53 match key {
54 NAME_FIELD => {
55 if name_field.is_some() {
56 return Err(FromValueError::DuplicateInstanceVariable {
57 name: NAME_FIELD.into(),
58 });
59 }
60
61 let name: &StringValue = ctx.from_value(value)?;
62 let name =
63 std::str::from_utf8(name.value()).map_err(FromValueError::new_other)?;
64
65 name_field = Some(name.into());
66 }
67 LIST_FIELD => {
68 if list_field.is_some() {
69 return Err(FromValueError::DuplicateInstanceVariable {
70 name: LIST_FIELD.into(),
71 });
72 }
73
74 list_field = Some(ctx.from_value(value)?);
75 }
76 TRIGGER_FIELD => {
77 if trigger_field.is_some() {
78 return Err(FromValueError::DuplicateInstanceVariable {
79 name: TRIGGER_FIELD.into(),
80 });
81 }
82
83 trigger_field = Some(ctx.from_value(value)?);
84 }
85 SWITCH_ID_FIELD => {
86 if switch_id_field.is_some() {
87 return Err(FromValueError::DuplicateInstanceVariable {
88 name: SWITCH_ID_FIELD.into(),
89 });
90 }
91
92 switch_id_field = Some(ctx.from_value(value)?);
93 }
94 ID_FIELD => {
95 if id_field.is_some() {
96 return Err(FromValueError::DuplicateInstanceVariable {
97 name: ID_FIELD.into(),
98 });
99 }
100
101 id_field = Some(ctx.from_value(value)?);
102 }
103 _ => {
104 return Err(FromValueError::UnknownInstanceVariable { name: key.into() });
105 }
106 }
107 }
108
109 let name = name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
110 name: NAME_FIELD.into(),
111 })?;
112 let list = list_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
113 name: LIST_FIELD.into(),
114 })?;
115 let trigger = trigger_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
116 name: TRIGGER_FIELD.into(),
117 })?;
118 let switch_id = switch_id_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
119 name: SWITCH_ID_FIELD.into(),
120 })?;
121 let id = id_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
122 name: ID_FIELD.into(),
123 })?;
124
125 Ok(Self {
126 name,
127 list,
128 trigger,
129 switch_id,
130 id,
131 })
132 }
133}
134
135impl IntoValue for CommonEvent {
136 fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
137 let object_name = arena.create_symbol(OBJECT_NAME.into());
138
139 let name_field_key = arena.create_symbol(NAME_FIELD.into());
140 let list_field_key = arena.create_symbol(LIST_FIELD.into());
141 let trigger_field_key = arena.create_symbol(TRIGGER_FIELD.into());
142 let switch_id_field_key = arena.create_symbol(SWITCH_ID_FIELD.into());
143 let id_field_key = arena.create_symbol(ID_FIELD.into());
144
145 let name_field_value = arena.create_string(self.name.into()).into();
146 let list_field_value = self.list.into_value(arena)?;
147 let trigger_field_value = self.trigger.into_value(arena)?;
148 let switch_id_field_value = self.switch_id.into_value(arena)?;
149 let id_field_value = self.id.into_value(arena)?;
150
151 let fields = vec![
152 (name_field_key, name_field_value),
153 (list_field_key, list_field_value),
154 (trigger_field_key, trigger_field_value),
155 (switch_id_field_key, switch_id_field_value),
156 (id_field_key, id_field_value),
157 ];
158
159 let object = arena.create_object(object_name, fields);
160
161 Ok(object.into())
162 }
163}