rpgmxp_types/
event_command.rs1use crate::EventCommandParameter;
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::SymbolValue;
9use ruby_marshal::Value;
10use ruby_marshal::ValueArena;
11use ruby_marshal::ValueHandle;
12
13const OBJECT_NAME: &[u8] = b"RPG::EventCommand";
14
15const PARAMETERS_FIELD: &[u8] = b"@parameters";
16const CODE_FIELD: &[u8] = b"@code";
17const INDENT_FIELD: &[u8] = b"@indent";
18
19#[derive(Debug, serde::Serialize, serde::Deserialize)]
21pub struct EventCommand {
22 pub parameters: Vec<EventCommandParameter>,
24 pub indent: i32,
26 pub code: i32,
28}
29
30impl<'a> FromValue<'a> for EventCommand {
31 fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
32 let object: &ObjectValue = FromValue::from_value(ctx, value)?;
33 let name = object.name();
34 let name: &SymbolValue = ctx.from_value(name.into())?;
35 let name = name.value();
36
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 parameters_field = None;
44 let mut indent_field = None;
45 let mut code_field = None;
46
47 for (key, value) in instance_variables.iter().copied() {
48 let key: &SymbolValue = ctx.from_value(key.into())?;
49 let key = key.value();
50
51 match key {
52 PARAMETERS_FIELD => {
53 if parameters_field.is_some() {
54 return Err(FromValueError::DuplicateInstanceVariable {
55 name: PARAMETERS_FIELD.into(),
56 });
57 }
58
59 parameters_field = Some(ctx.from_value(value)?);
60 }
61 CODE_FIELD => {
62 if code_field.is_some() {
63 return Err(FromValueError::DuplicateInstanceVariable {
64 name: CODE_FIELD.into(),
65 });
66 }
67
68 code_field = Some(ctx.from_value(value)?);
69 }
70 INDENT_FIELD => {
71 if indent_field.is_some() {
72 return Err(FromValueError::DuplicateInstanceVariable {
73 name: INDENT_FIELD.into(),
74 });
75 }
76
77 indent_field = Some(ctx.from_value(value)?);
78 }
79 _ => {
80 return Err(FromValueError::UnknownInstanceVariable { name: key.into() });
81 }
82 }
83 }
84
85 let parameters =
86 parameters_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
87 name: PARAMETERS_FIELD.into(),
88 })?;
89 let indent = indent_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
90 name: INDENT_FIELD.into(),
91 })?;
92 let code = code_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
93 name: CODE_FIELD.into(),
94 })?;
95
96 Ok(Self {
97 parameters,
98 indent,
99 code,
100 })
101 }
102}
103
104impl IntoValue for EventCommand {
105 fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
106 let object_name = arena.create_symbol(OBJECT_NAME.into());
107
108 let parameters_field_key = arena.create_symbol(PARAMETERS_FIELD.into());
109 let code_field_key = arena.create_symbol(CODE_FIELD.into());
110 let indent_field_key = arena.create_symbol(INDENT_FIELD.into());
111
112 let parameters_field_value = self.parameters.into_value(arena)?;
113 let code_field_value = self.code.into_value(arena)?;
114 let indent_field_value = self.indent.into_value(arena)?;
115
116 let fields = vec![
117 (parameters_field_key, parameters_field_value),
118 (code_field_key, code_field_value),
119 (indent_field_key, indent_field_value),
120 ];
121
122 let object = arena.create_object(object_name, fields);
123
124 Ok(object.into())
125 }
126}