1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct Machine {
10 pub name: String,
12 pub source_file: Option<String>,
14 pub rom_of: Option<String>,
16 pub clone_of: Option<String>,
18 pub is_bios: Option<bool>,
20 pub is_device: Option<bool>,
22 pub runnable: Option<bool>,
24 pub is_mechanical: Option<bool>,
26 pub sample_of: Option<String>,
28 pub description: Option<String>,
30 pub year: Option<String>,
32 pub manufacturer: Option<String>,
34 pub bios_sets: Vec<BiosSet>,
36 pub roms: Vec<Rom>,
38 pub device_refs: Vec<DeviceRef>,
40 pub software_list: Vec<Software>,
42 pub samples: Vec<Sample>,
44 pub driver_status: Option<String>,
46 pub languages: Vec<String>,
48 pub players: Option<String>,
50 pub series: Option<String>,
52 pub category: Option<String>,
54 pub subcategory: Option<String>,
56 pub is_mature: Option<bool>,
58 pub history_sections: Vec<HistorySection>,
60 pub disks: Vec<Disk>,
62 pub extended_data: Option<ExtendedData>,
64 pub resources: Vec<Resource>,
66}
67
68impl Machine {
69 pub fn new(name: String) -> Self {
71 Machine {
72 name,
73 source_file: None,
74 rom_of: None,
75 clone_of: None,
76 is_bios: None,
77 is_device: None,
78 runnable: None,
79 is_mechanical: None,
80 sample_of: None,
81 description: None,
82 year: None,
83 manufacturer: None,
84 bios_sets: Vec::new(),
85 roms: Vec::new(),
86 device_refs: Vec::new(),
87 software_list: Vec::new(),
88 samples: Vec::new(),
89 driver_status: None,
90 languages: Vec::new(),
91 players: None,
92 series: None,
93 category: None,
94 subcategory: None,
95 is_mature: None,
96 history_sections: Vec::new(),
97 disks: Vec::new(),
98 extended_data: Some(Default::default()),
99 resources: Vec::new(),
100 }
101 }
102 pub fn combine(&mut self, other: &Machine) {
104 if self.source_file.is_none() {
105 self.source_file = other.source_file.clone();
106 }
107 if self.rom_of.is_none() {
108 self.rom_of = other.rom_of.clone();
109 }
110 if self.clone_of.is_none() {
111 self.clone_of = other.clone_of.clone();
112 }
113 if self.is_bios.is_none() {
114 self.is_bios = other.is_bios;
115 }
116 if self.is_device.is_none() {
117 self.is_device = other.is_device;
118 }
119 if self.runnable.is_none() {
120 self.runnable = other.runnable;
121 }
122 if self.is_mechanical.is_none() {
123 self.is_mechanical = other.is_mechanical;
124 }
125 if self.sample_of.is_none() {
126 self.sample_of = other.sample_of.clone();
127 }
128 if self.description.is_none() {
129 self.description = other.description.clone();
130 }
131 if self.year.is_none() {
132 self.year = other.year.clone();
133 }
134 if self.manufacturer.is_none() {
135 self.manufacturer = other.manufacturer.clone();
136 }
137 if self.driver_status.is_none() {
138 self.driver_status = other.driver_status.clone();
139 }
140 if self.players.is_none() {
141 self.players = other.players.clone();
142 }
143 if self.series.is_none() {
144 self.series = other.series.clone();
145 }
146 if self.category.is_none() {
147 self.category = other.category.clone();
148 }
149 if self.subcategory.is_none() {
150 self.subcategory = other.subcategory.clone();
151 }
152 if self.is_mature.is_none() {
153 self.is_mature = other.is_mature;
154 }
155
156 self.bios_sets.extend(other.bios_sets.clone());
157 self.roms.extend(other.roms.clone());
158 self.device_refs.extend(other.device_refs.clone());
159 self.software_list.extend(other.software_list.clone());
160 self.samples.extend(other.samples.clone());
161 self.languages.extend(other.languages.clone());
162 self.history_sections.extend(other.history_sections.clone());
163 self.disks.extend(other.disks.clone());
164 self.resources.extend(other.resources.clone());
165
166 match (&mut self.extended_data, &other.extended_data) {
167 (Some(self_data), Some(other_data)) => {
168 self_data.combine(other_data);
169 }
170 (None, Some(other_data)) => {
171 self.extended_data = Some(other_data.clone());
172 }
173 _ => {}
174 }
175 }
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct BiosSet {
181 pub name: String,
183 pub description: String,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct Rom {
190 pub name: String,
192 pub size: u64,
194 pub merge: Option<String>,
196 pub status: Option<String>,
198 pub crc: Option<String>,
200 pub sha1: Option<String>,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct DeviceRef {
207 pub name: String,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct Software {
214 pub name: String,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct Sample {
221 pub name: String,
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct Disk {
228 pub name: String,
230 pub sha1: Option<String>,
232 pub merge: Option<String>,
234 pub status: Option<String>,
236 pub region: Option<String>,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct HistorySection {
243 pub name: String,
245 pub text: String,
247 pub order: usize,
249}
250
251#[derive(Debug, Serialize, Deserialize, Clone, Default)]
256pub struct ExtendedData {
257 pub name: Option<String>,
259 pub manufacturer: Option<String>,
261 pub players: Option<String>,
263 pub is_parent: Option<bool>,
265 pub year: Option<String>,
267}
268
269impl ExtendedData {
270 pub fn combine(&mut self, other: &ExtendedData) {
272 if self.name.is_none() {
273 self.name = other.name.clone();
274 }
275 if self.manufacturer.is_none() {
276 self.manufacturer = other.manufacturer.clone();
277 }
278 if self.players.is_none() {
279 self.players = other.players.clone();
280 }
281 if self.is_parent.is_none() {
282 self.is_parent = other.is_parent;
283 }
284 if self.year.is_none() {
285 self.year = other.year.clone();
286 }
287 }
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct Resource {
293 pub type_: String,
295 pub name: String,
297 pub size: u64,
299 pub crc: String,
301 pub sha1: String,
303}