rpgmvx_types/
move_command_parameter.rs

1use crate::Bgm;
2use crate::Se;
3use ruby_marshal::FromValue;
4use ruby_marshal::FromValueContext;
5use ruby_marshal::FromValueError;
6use ruby_marshal::IntoValue;
7use ruby_marshal::IntoValueError;
8use ruby_marshal::SymbolValue;
9use ruby_marshal::Value;
10use ruby_marshal::ValueArena;
11use ruby_marshal::ValueHandle;
12use ruby_marshal::ValueKind;
13
14#[derive(Debug)]
15pub enum MoveCommandParameterFromValueError {
16    UnexpectedValueKind { kind: ValueKind },
17}
18
19impl std::fmt::Display for MoveCommandParameterFromValueError {
20    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21        match self {
22            Self::UnexpectedValueKind { kind } => {
23                write!(
24                    f,
25                    "unexpected value kind for move command parameter: {kind:?}"
26                )
27            }
28        }
29    }
30}
31
32impl std::error::Error for MoveCommandParameterFromValueError {}
33
34#[derive(Debug, serde::Serialize, serde::Deserialize)]
35pub enum MoveCommandParameter {
36    Int(i32),
37    Se(Se),
38    Bgm(Bgm),
39    String(String),
40}
41
42impl<'a> FromValue<'a> for MoveCommandParameter {
43    fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
44        match value {
45            Value::Fixnum(value) => {
46                let value = value.value();
47                Ok(Self::Int(value))
48            }
49            Value::Object(object_value) => {
50                let name = object_value.name();
51                let name: &SymbolValue = ctx.from_value(name.into())?;
52                let name = name.value();
53
54                match name {
55                    crate::se::OBJECT_NAME => {
56                        let value = FromValue::from_value(ctx, value)?;
57                        Ok(Self::Se(value))
58                    }
59                    crate::bgm::OBJECT_NAME => {
60                        let value = FromValue::from_value(ctx, value)?;
61                        Ok(Self::Bgm(value))
62                    }
63                    _ => Err(FromValueError::UnexpectedObjectName { name: name.into() }),
64                }
65            }
66            Value::String(value) => {
67                let value = value.value();
68                let value = std::str::from_utf8(value)
69                    .map_err(FromValueError::new_other)?
70                    .to_string();
71                Ok(Self::String(value))
72            }
73            _ => Err(FromValueError::new_other(
74                MoveCommandParameterFromValueError::UnexpectedValueKind { kind: value.kind() },
75            )),
76        }
77    }
78}
79
80impl IntoValue for MoveCommandParameter {
81    fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
82        match self {
83            Self::Int(value) => value.into_value(arena),
84            Self::Se(value) => value.into_value(arena),
85            Self::String(value) => Ok(arena.create_string(value.into()).into()),
86            Self::Bgm(value) => value.into_value(arena),
87        }
88    }
89}