rpgmxp_types/
event_page_graphic.rs1use ruby_marshal::FromValue;
2use ruby_marshal::FromValueContext;
3use ruby_marshal::FromValueError;
4use ruby_marshal::IntoValue;
5use ruby_marshal::IntoValueError;
6use ruby_marshal::ObjectValue;
7use ruby_marshal::StringValue;
8use ruby_marshal::SymbolValue;
9use ruby_marshal::Value;
10use ruby_marshal::ValueArena;
11use ruby_marshal::ValueHandle;
12
13const OBJECT_NAME: &[u8] = b"RPG::Event::Page::Graphic";
14
15const OPACITY_FIELD: &[u8] = b"@opacity";
16const CHARACTER_NAME_FIELD: &[u8] = b"@character_name";
17const PATTERN_FIELD: &[u8] = b"@pattern";
18const TILE_ID_FIELD: &[u8] = b"@tile_id";
19const DIRECTION_FIELD: &[u8] = b"@direction";
20const BLEND_TYPE_FIELD: &[u8] = b"@blend_type";
21const CHARACTER_HUE_FIELD: &[u8] = b"@character_hue";
22
23#[derive(Debug, serde::Deserialize, serde::Serialize)]
24pub struct EventPageGraphic {
25 pub opacity: i32,
26 pub character_name: String,
27 pub pattern: i32,
28 pub tile_id: i32,
29 pub direction: i32,
30 pub blend_type: i32,
31 pub character_hue: i32,
32}
33
34impl<'a> FromValue<'a> for EventPageGraphic {
35 fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
36 let object: &ObjectValue = FromValue::from_value(ctx, value)?;
37 let name = object.name();
38 let name: &SymbolValue = ctx.from_value(name.into())?;
39 let name = name.value();
40
41 if name != OBJECT_NAME {
42 return Err(FromValueError::UnexpectedObjectName { name: name.into() });
43 }
44
45 let instance_variables = object.instance_variables();
46
47 let mut opacity_field = None;
48 let mut character_name_field = None;
49 let mut pattern_field = None;
50 let mut tile_id_field = None;
51 let mut direction_field = None;
52 let mut blend_type_field = None;
53 let mut character_hue_field = None;
54
55 for (key, value) in instance_variables.iter().copied() {
56 let key: &SymbolValue = ctx.from_value(key.into())?;
57 let key = key.value();
58
59 match key {
60 OPACITY_FIELD => {
61 if opacity_field.is_some() {
62 return Err(FromValueError::DuplicateInstanceVariable {
63 name: OPACITY_FIELD.into(),
64 });
65 }
66
67 let opacity: i32 = ctx.from_value(value)?;
68 opacity_field = Some(opacity);
69 }
70 CHARACTER_NAME_FIELD => {
71 if character_name_field.is_some() {
72 return Err(FromValueError::DuplicateInstanceVariable {
73 name: CHARACTER_NAME_FIELD.into(),
74 });
75 }
76
77 let character_name: &StringValue = ctx.from_value(value)?;
78 let character_name = std::str::from_utf8(character_name.value())
79 .map_err(FromValueError::new_other)?;
80
81 character_name_field = Some(character_name.into());
82 }
83 PATTERN_FIELD => {
84 if pattern_field.is_some() {
85 return Err(FromValueError::DuplicateInstanceVariable {
86 name: PATTERN_FIELD.into(),
87 });
88 }
89
90 let pattern: i32 = ctx.from_value(value)?;
91 pattern_field = Some(pattern);
92 }
93 TILE_ID_FIELD => {
94 if tile_id_field.is_some() {
95 return Err(FromValueError::DuplicateInstanceVariable {
96 name: TILE_ID_FIELD.into(),
97 });
98 }
99
100 let tile_id: i32 = ctx.from_value(value)?;
101 tile_id_field = Some(tile_id);
102 }
103 DIRECTION_FIELD => {
104 if direction_field.is_some() {
105 return Err(FromValueError::DuplicateInstanceVariable {
106 name: DIRECTION_FIELD.into(),
107 });
108 }
109
110 let direction: i32 = ctx.from_value(value)?;
111 direction_field = Some(direction);
112 }
113 BLEND_TYPE_FIELD => {
114 if blend_type_field.is_some() {
115 return Err(FromValueError::DuplicateInstanceVariable {
116 name: BLEND_TYPE_FIELD.into(),
117 });
118 }
119
120 let blend_type: i32 = ctx.from_value(value)?;
121 blend_type_field = Some(blend_type);
122 }
123 CHARACTER_HUE_FIELD => {
124 if character_hue_field.is_some() {
125 return Err(FromValueError::DuplicateInstanceVariable {
126 name: CHARACTER_HUE_FIELD.into(),
127 });
128 }
129
130 let character_hue: i32 = ctx.from_value(value)?;
131 character_hue_field = Some(character_hue);
132 }
133 _ => return Err(FromValueError::UnknownInstanceVariable { name: key.into() }),
134 }
135 }
136
137 let opacity = opacity_field.ok_or(FromValueError::MissingInstanceVariable {
138 name: OPACITY_FIELD.into(),
139 })?;
140 let character_name =
141 character_name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
142 name: CHARACTER_NAME_FIELD.into(),
143 })?;
144 let pattern = pattern_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
145 name: PATTERN_FIELD.into(),
146 })?;
147 let tile_id = tile_id_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
148 name: TILE_ID_FIELD.into(),
149 })?;
150 let direction = direction_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
151 name: DIRECTION_FIELD.into(),
152 })?;
153 let blend_type =
154 blend_type_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
155 name: BLEND_TYPE_FIELD.into(),
156 })?;
157 let character_hue =
158 character_hue_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
159 name: CHARACTER_HUE_FIELD.into(),
160 })?;
161
162 Ok(Self {
163 opacity,
164 character_name,
165 pattern,
166 tile_id,
167 direction,
168 blend_type,
169 character_hue,
170 })
171 }
172}
173
174impl IntoValue for EventPageGraphic {
175 fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
176 let object_name = arena.create_symbol(OBJECT_NAME.into());
177
178 let opacity_field_key = arena.create_symbol(OPACITY_FIELD.into());
179 let character_name_field_key = arena.create_symbol(CHARACTER_NAME_FIELD.into());
180 let pattern_field_key = arena.create_symbol(PATTERN_FIELD.into());
181 let tile_id_field_key = arena.create_symbol(TILE_ID_FIELD.into());
182 let direction_field_key = arena.create_symbol(DIRECTION_FIELD.into());
183 let blend_type_field_key = arena.create_symbol(BLEND_TYPE_FIELD.into());
184 let character_hue_field_key = arena.create_symbol(CHARACTER_HUE_FIELD.into());
185
186 let opacity_field_value = self.opacity.into_value(arena)?;
187 let character_name_field_value = arena.create_string(self.character_name.into()).into();
188 let pattern_field_value = self.pattern.into_value(arena)?;
189 let tile_id_field_value = self.tile_id.into_value(arena)?;
190 let direction_field_value = self.direction.into_value(arena)?;
191 let blend_type_field_value = self.blend_type.into_value(arena)?;
192 let character_hue_field_value = self.character_hue.into_value(arena)?;
193
194 let fields = vec![
195 (opacity_field_key, opacity_field_value),
196 (pattern_field_key, pattern_field_value),
197 (character_name_field_key, character_name_field_value),
198 (tile_id_field_key, tile_id_field_value),
199 (direction_field_key, direction_field_value),
200 (blend_type_field_key, blend_type_field_value),
201 (character_hue_field_key, character_hue_field_value),
202 ];
203 let object = arena.create_object(object_name, fields);
204
205 Ok(object.into())
206 }
207}