rpgmvx_types/
event_command_parameter.rs1use crate::Bgm;
2use crate::Bgs;
3use crate::Color;
4use crate::Me;
5use crate::MoveCommand;
6use crate::MoveRoute;
7use crate::Se;
8use crate::Tone;
9use ruby_marshal::DisplayByteString;
10use ruby_marshal::FromValue;
11use ruby_marshal::FromValueContext;
12use ruby_marshal::FromValueError;
13use ruby_marshal::IntoValue;
14use ruby_marshal::IntoValueError;
15use ruby_marshal::StringValue;
16use ruby_marshal::SymbolValue;
17use ruby_marshal::Value;
18use ruby_marshal::ValueArena;
19use ruby_marshal::ValueHandle;
20use ruby_marshal::ValueKind;
21
22#[derive(Debug)]
23pub enum EventCommandParameterFromValueError {
24 UnexpectedValueKind { kind: ValueKind },
25 UnexpectedUserDefinedName { name: Vec<u8> },
26 EmptyArray,
27 UnexpectedArrayValueKind { kind: ValueKind },
28}
29
30impl std::fmt::Display for EventCommandParameterFromValueError {
31 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
32 match self {
33 Self::UnexpectedValueKind { kind } => {
34 write!(
35 f,
36 "unexpected value kind for event command parameter: {kind:?}"
37 )
38 }
39 Self::UnexpectedUserDefinedName { name } => {
40 let name = DisplayByteString(name);
41 write!(
42 f,
43 "unexpected event command parameter user defined name: {name}"
44 )
45 }
46 Self::EmptyArray => write!(f, "the event command parameter array is empty"),
47 Self::UnexpectedArrayValueKind { kind } => {
48 write!(
49 f,
50 "unexpected event command parameter array value kind: {kind:?}"
51 )
52 }
53 }
54 }
55}
56
57impl std::error::Error for EventCommandParameterFromValueError {}
58
59#[derive(Debug, serde::Serialize, serde::Deserialize)]
60#[serde(tag = "type", content = "data")]
61pub enum EventCommandParameter {
62 #[serde(rename = "string")]
63 String(String),
64 #[serde(rename = "int")]
65 Int(i32),
66 #[serde(rename = "bool")]
67 Bool(bool),
68 #[serde(rename = "nil")]
69 Nil,
70 #[serde(rename = "string-array")]
71 StringArray(Vec<String>),
72 #[serde(rename = "move-route")]
73 MoveRoute(MoveRoute),
74 #[serde(rename = "move-command")]
75 MoveCommand(MoveCommand),
76 #[serde(rename = "se")]
77 Se(Se),
78 #[serde(rename = "tone")]
79 Tone(Tone),
80 #[serde(rename = "color")]
81 Color(Color),
82 #[serde(rename = "bgm")]
83 Bgm(Bgm),
84 #[serde(rename = "bgs")]
85 Bgs(Bgs),
86 #[serde(rename = "me")]
87 Me(Me),
88}
89
90impl<'a> FromValue<'a> for EventCommandParameter {
91 fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
92 match value {
93 Value::String(value) => {
94 let value = value.value();
95 let value = std::str::from_utf8(value)
96 .map_err(FromValueError::new_other)?
97 .to_string();
98 Ok(Self::String(value))
99 }
100 Value::Fixnum(value) => {
101 let value = value.value();
102 Ok(Self::Int(value))
103 }
104 Value::Bool(value) => {
105 let value = value.value();
106 Ok(Self::Bool(value))
107 }
108 Value::Nil(_) => Ok(Self::Nil),
109 Value::Array(value) => {
110 let value = value.value();
111 let first = value.first().ok_or(FromValueError::new_other(
114 EventCommandParameterFromValueError::EmptyArray,
115 ))?;
116 let first: &Value = ctx.from_value(*first)?;
117 let first_kind = first.kind();
118
119 match first_kind {
120 ValueKind::String => {
121 let mut new_value = Vec::with_capacity(value.len());
122 for value in value.iter().copied() {
123 let value: &StringValue = ctx.from_value(value)?;
124 let value = std::str::from_utf8(value.value())
125 .map_err(FromValueError::new_other)?
126 .to_string();
127 new_value.push(value);
128 }
129
130 Ok(Self::StringArray(new_value))
131 }
132 _ => Err(FromValueError::new_other(
133 EventCommandParameterFromValueError::UnexpectedArrayValueKind {
134 kind: first_kind,
135 },
136 )),
137 }
138 }
139 Value::Object(object_value) => {
140 let name = object_value.name();
141 let name: &SymbolValue = ctx.from_value(name.into())?;
142 let name = name.value();
143
144 match name {
145 crate::move_route::OBJECT_NAME => {
146 let value = FromValue::from_value(ctx, value)?;
147 Ok(Self::MoveRoute(value))
148 }
149 crate::move_command::OBJECT_NAME => {
150 let value = FromValue::from_value(ctx, value)?;
151 Ok(Self::MoveCommand(value))
152 }
153 crate::se::OBJECT_NAME => {
154 let value = FromValue::from_value(ctx, value)?;
155 Ok(Self::Se(value))
156 }
157 crate::bgm::OBJECT_NAME => {
158 let value = FromValue::from_value(ctx, value)?;
159 Ok(Self::Bgm(value))
160 }
161 crate::bgs::OBJECT_NAME => {
162 let value = FromValue::from_value(ctx, value)?;
163 Ok(Self::Bgs(value))
164 }
165 crate::me::OBJECT_NAME => {
166 let value = FromValue::from_value(ctx, value)?;
167 Ok(Self::Me(value))
168 }
169 _ => Err(FromValueError::UnexpectedObjectName { name: name.into() }),
170 }
171 }
172 Value::UserDefined(user_defined_value) => {
173 let name = user_defined_value.name();
174 let name: &SymbolValue = ctx.from_value(name.into())?;
175 let name = name.value();
176
177 match name {
178 crate::tone::USER_DEFINED_NAME => {
179 let value = FromValue::from_value(ctx, value)?;
180 Ok(Self::Tone(value))
181 }
182 crate::color::USER_DEFINED_NAME => {
183 let value = FromValue::from_value(ctx, value)?;
184 Ok(Self::Color(value))
185 }
186 _ => Err(FromValueError::new_other(
187 EventCommandParameterFromValueError::UnexpectedUserDefinedName {
188 name: name.into(),
189 },
190 )),
191 }
192 }
193 _ => Err(FromValueError::new_other(
194 EventCommandParameterFromValueError::UnexpectedValueKind { kind: value.kind() },
195 )),
196 }
197 }
198}
199
200impl IntoValue for EventCommandParameter {
201 fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
202 match self {
203 Self::String(value) => Ok(arena.create_string(value.into()).into()),
204 Self::Int(value) => value.into_value(arena),
205 Self::Bool(value) => value.into_value(arena),
206 Self::Nil => Ok(arena.create_nil().into()),
207 Self::StringArray(value) => {
208 let values: Vec<_> = value
209 .into_iter()
210 .map(|value| arena.create_string(value.into()).into())
211 .collect();
212 Ok(arena.create_array(values).into())
213 }
214 Self::MoveRoute(value) => value.into_value(arena),
215 Self::MoveCommand(value) => value.into_value(arena),
216 Self::Se(value) => value.into_value(arena),
217 Self::Tone(value) => value.into_value(arena),
218 Self::Color(value) => value.into_value(arena),
219 Self::Bgm(value) => value.into_value(arena),
220 Self::Bgs(value) => value.into_value(arena),
221 Self::Me(value) => value.into_value(arena),
222 }
223 }
224}