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