1use std::collections::HashMap;
2use std::path::PathBuf;
3use std::str::FromStr;
4
5use crate::utils::prelude::*;
6use anyhow::{format_err, Error};
7use roxmltree::Node;
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum Core {
12 Any,
13 CortexM0,
14 CortexM0Plus,
15 CortexM1,
16 CortexM3,
17 CortexM4,
18 CortexM7,
19 CortexM23,
20 CortexM33,
21 CortexM35P,
22 CortexM55,
23 CortexM85,
24 StarMC1,
25 SC000,
26 SC300,
27 ARMV8MBL,
28 ARMV8MML,
29 ARMV81MML,
30 CortexR4,
31 CortexR5,
32 CortexR7,
33 CortexR8,
34 CortexA5,
35 CortexA7,
36 CortexA8,
37 CortexA9,
38 CortexA15,
39 CortexA17,
40 CortexA32,
41 CortexA35,
42 CortexA53,
43 CortexA57,
44 CortexA72,
45 CortexA73,
46}
47
48impl FromStr for Core {
49 type Err = Error;
50 fn from_str(from: &str) -> Result<Self, Error> {
51 match from {
52 "Cortex-M0" => Ok(Core::CortexM0),
53 "Cortex-M0+" => Ok(Core::CortexM0Plus),
54 "Cortex-M1" => Ok(Core::CortexM1),
55 "Cortex-M3" => Ok(Core::CortexM3),
56 "Cortex-M4" => Ok(Core::CortexM4),
57 "Cortex-M7" => Ok(Core::CortexM7),
58 "Cortex-M23" => Ok(Core::CortexM23),
59 "Cortex-M33" => Ok(Core::CortexM33),
60 "Cortex-M35P" => Ok(Core::CortexM35P),
61 "Cortex-M55" => Ok(Core::CortexM55),
62 "Cortex-M85" => Ok(Core::CortexM85),
63 "Star-MC1" => Ok(Core::StarMC1),
64 "SC000" => Ok(Core::SC000),
65 "SC300" => Ok(Core::SC300),
66 "ARMV8MBL" => Ok(Core::ARMV8MBL),
67 "ARMV8MML" => Ok(Core::ARMV8MML),
68 "Cortex-R4" => Ok(Core::CortexR4),
69 "Cortex-R5" => Ok(Core::CortexR5),
70 "Cortex-R7" => Ok(Core::CortexR7),
71 "Cortex-R8" => Ok(Core::CortexR8),
72 "Cortex-A5" => Ok(Core::CortexA5),
73 "Cortex-A7" => Ok(Core::CortexA7),
74 "Cortex-A8" => Ok(Core::CortexA8),
75 "Cortex-A9" => Ok(Core::CortexA9),
76 "Cortex-A15" => Ok(Core::CortexA15),
77 "Cortex-A17" => Ok(Core::CortexA17),
78 "Cortex-A32" => Ok(Core::CortexA32),
79 "Cortex-A35" => Ok(Core::CortexA35),
80 "Cortex-A53" => Ok(Core::CortexA53),
81 "Cortex-A57" => Ok(Core::CortexA57),
82 "Cortex-A72" => Ok(Core::CortexA72),
83 "Cortex-A73" => Ok(Core::CortexA73),
84 "*" => Ok(Core::Any),
85 unknown => Err(format_err!("Unknown core {}", unknown)),
86 }
87 }
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub enum FPU {
92 None,
93 SinglePrecision,
94 DoublePrecision,
95}
96
97impl FromStr for FPU {
98 type Err = Error;
99 fn from_str(from: &str) -> Result<Self, Error> {
100 match from {
101 "FPU" => Ok(FPU::SinglePrecision),
102 "SP_FPU" => Ok(FPU::SinglePrecision),
103 "1" => Ok(FPU::SinglePrecision),
104 "None" => Ok(FPU::None),
105 "0" => Ok(FPU::None),
106 "DP_FPU" => Ok(FPU::DoublePrecision),
107 "2" => Ok(FPU::DoublePrecision),
108 unknown => Err(format_err!("Unknown fpu {}", unknown)),
109 }
110 }
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub enum MPU {
115 NotPresent,
116 Present,
117}
118
119impl FromStr for MPU {
120 type Err = Error;
121 fn from_str(from: &str) -> Result<Self, Error> {
122 match from {
123 "MPU" => Ok(MPU::Present),
124 "1" => Ok(MPU::Present),
125 "None" => Ok(MPU::NotPresent),
126 "0" => Ok(MPU::NotPresent),
127 unknown => Err(format_err!("Unknown fpu {}", unknown)),
128 }
129 }
130}
131
132#[derive(Debug, Clone, Deserialize, Serialize)]
133pub struct Processor {
134 pub core: Core,
135 pub fpu: FPU,
136 pub mpu: MPU,
137 pub ap: AccessPort,
138 pub dp: u8,
139 pub address: Option<u32>,
140 pub svd: Option<String>,
141 pub name: Option<String>,
142 pub unit: usize,
143 pub default_reset_sequence: Option<String>,
144}
145
146#[derive(Debug, Clone)]
147struct ProcessorBuilder {
148 core: Option<Core>,
149 units: Option<usize>,
150 name: Option<String>,
151 fpu: Option<FPU>,
152 mpu: Option<MPU>,
153}
154
155impl ProcessorBuilder {
156 fn merge(self, other: &Self) -> Self {
157 Self {
158 core: self.core.or(other.core.clone()),
159 units: self.units.or(other.units),
160 name: self.name.or(other.name.clone()),
161 fpu: self.fpu.or(other.fpu.clone()),
162 mpu: self.mpu.or(other.mpu.clone()),
163 }
164 }
165 fn build(self, debugs: &[Debug]) -> Result<Vec<Processor>, Error> {
166 let units = self.units.unwrap_or(1);
167 let name = self.name.clone();
168
169 (0..units)
170 .map(|unit| {
171 let debugs_iterator = debugs.iter().filter(|debug| {
178 debug
180 .name
181 .as_ref()
182 .map_or(true, |n| Some(n) == name.as_ref())
183 && debug.unit.map_or(true, |u| u == unit)
184 });
185
186 Ok(Processor {
187 core: self
188 .core
189 .clone()
190 .ok_or_else(|| format_err!("No Core found!"))?,
191 fpu: self.fpu.clone().unwrap_or(FPU::None),
192 mpu: self.mpu.clone().unwrap_or(MPU::NotPresent),
193 dp: debugs_iterator
194 .clone()
195 .find_map(|d| d.dp)
196 .unwrap_or_default(),
197 ap: debugs_iterator
198 .clone()
199 .find_map(|d| d.ap)
200 .unwrap_or_default(),
201 address: debugs_iterator.clone().find_map(|d| d.address),
202 svd: debugs_iterator.clone().find_map(|d| d.svd.clone()),
203 name: name.clone(),
204 unit,
205 default_reset_sequence: debugs_iterator
206 .clone()
207 .find_map(|d| d.default_reset_sequence.clone()),
208 })
209 })
210 .collect::<Result<Vec<_>, _>>()
211 }
212}
213
214impl FromElem for ProcessorBuilder {
215 fn from_elem(e: &Node) -> Result<Self, Error> {
216 Ok(ProcessorBuilder {
217 core: attr_parse(e, "Dcore").ok(),
218 units: attr_parse(e, "Punits").ok(),
219 fpu: attr_parse(e, "Dfpu").ok(),
220 mpu: attr_parse(e, "Dmpu").ok(),
221 name: attr_parse(e, "Pname").ok(),
222 })
223 }
224}
225
226#[derive(Debug, Clone)]
227struct ProcessorsBuilder(Vec<ProcessorBuilder>);
228
229impl ProcessorsBuilder {
230 fn merge(mut self, parent: &Option<Self>) -> Result<Self, Error> {
231 if let Some(parent) = parent {
232 if let [parent] = &parent.0[..] {
233 self.0 = self.0.into_iter().map(|x| x.merge(parent)).collect();
234 } else {
235 Err(format_err!(
236 "Support for two parent processors not implemented!"
237 ))?;
238 }
239 }
240 Ok(self)
241 }
242
243 fn merge_into(&mut self, other: Self) {
244 self.0.extend(other.0);
245 }
246
247 fn build(self, debugs: Vec<Debug>) -> Result<Vec<Processor>, Error> {
248 let mut vec = vec![];
249 for processor in self.0.into_iter() {
250 vec.extend(processor.build(&debugs)?);
251 }
252 Ok(vec)
253 }
254}
255
256impl FromElem for ProcessorsBuilder {
257 fn from_elem(e: &Node) -> Result<Self, Error> {
258 Ok(ProcessorsBuilder(vec![ProcessorBuilder::from_elem(e)?]))
259 }
260}
261
262#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
263pub enum AccessPort {
264 Index(u8),
265 Address(u64),
266}
267impl Default for AccessPort {
268 fn default() -> Self {
269 Self::Index(0)
270 }
271}
272#[derive(Debug, Clone, Deserialize, Serialize)]
273pub struct Debug {
274 pub dp: Option<u8>,
275 pub ap: Option<AccessPort>,
276 pub address: Option<u32>,
277 pub svd: Option<String>,
278 pub name: Option<String>,
279 pub unit: Option<usize>,
280 pub default_reset_sequence: Option<String>,
281}
282
283#[derive(Debug, Clone)]
284struct DebugBuilder {
285 dp: Option<u8>,
286 ap: Option<AccessPort>,
287 address: Option<u32>,
288 svd: Option<String>,
289 name: Option<String>,
290 unit: Option<usize>,
291 default_reset_sequence: Option<String>,
292}
293
294impl DebugBuilder {
295 fn build(self) -> Debug {
296 Debug {
297 dp: self.dp,
298 ap: self.ap,
299 address: self.address,
300 svd: self.svd,
301 name: self.name,
302 unit: self.unit,
303 default_reset_sequence: self.default_reset_sequence,
304 }
305 }
306}
307
308impl DebugBuilder {
309 fn from_elem_and_parent(e: &Node, p: &Node) -> Result<Self, Error> {
310 let c = p
311 .children()
312 .map(|n| n.tag_name().name())
313 .collect::<Vec<_>>();
314 let (dp, ap) = if c.contains(&"accessportV1") || c.contains(&"accessportV2") {
315 let __apid: u32 = attr_parse(e, "__apid")?;
316 let ap = p
317 .children()
318 .find(|c| {
319 c.tag_name().name().starts_with("accessportV")
320 && attr_parse(c, "__apid")
321 .map(|apid: u32| apid == __apid)
322 .unwrap_or(false)
323 })
324 .ok_or_else(|| anyhow::anyhow!("Unable do find Access Port with id {__apid:?}."))?;
325 match ap.tag_name().name() {
326 "accessportV1" => (
327 attr_parse(&ap, "__dp").ok(),
328 attr_parse(&ap, "index").ok().map(AccessPort::Index),
329 ),
330 "accessportV2" => (
331 attr_parse(&ap, "__dp").ok(),
332 attr_parse_hex(&ap, "address").ok().map(AccessPort::Address),
333 ),
334 _ => unreachable!(),
335 }
336 } else {
337 (
338 attr_parse(e, "__dp").ok(),
339 attr_parse(e, "__ap").ok().map(AccessPort::Index),
340 )
341 };
342
343 Ok(DebugBuilder {
344 dp,
345 ap,
346 address: attr_parse(e, "address").ok(),
347 svd: attr_parse(e, "svd").ok(),
348 name: attr_parse(e, "Pname").ok(),
349 unit: attr_parse(e, "Punit").ok(),
350 default_reset_sequence: attr_parse(e, "defaultResetSequence").ok(),
351 })
352 }
353}
354
355#[derive(Debug)]
356struct DebugsBuilder(Vec<DebugBuilder>);
357
358impl DebugsBuilder {
359 fn from_elem_and_parent(e: &Node, p: &Node) -> Result<Self, Error> {
360 Ok(DebugsBuilder(vec![DebugBuilder::from_elem_and_parent(
361 e, p,
362 )?]))
363 }
364}
365
366impl DebugsBuilder {
367 fn merge(mut self, parent: &Self) -> Self {
368 self.0.extend(parent.0.iter().cloned());
369 self
370 }
371
372 fn merge_into(&mut self, other: Self) {
373 self.0.extend(other.0)
374 }
375
376 fn build(self) -> Vec<Debug> {
377 self.0.into_iter().map(|debug| debug.build()).collect()
378 }
379}
380
381#[derive(Debug, Clone, Serialize, Deserialize)]
382pub struct MemoryPermissions {
383 pub read: bool,
384 pub write: bool,
385 pub execute: bool,
386 pub peripheral: bool,
387 pub secure: bool,
388 pub non_secure: bool,
389 pub non_secure_callable: bool,
390}
391
392impl MemoryPermissions {
393 fn from_str(input: &str) -> Self {
394 let mut ret = MemoryPermissions {
395 read: false,
396 write: false,
397 execute: false,
398 peripheral: false,
399 secure: false,
400 non_secure: false,
401 non_secure_callable: false,
402 };
403 for c in input.chars() {
404 match c {
405 'r' => ret.read = true,
406 'w' => ret.write = true,
407 'x' => ret.execute = true,
408 'p' => ret.peripheral = true,
409 's' => ret.secure = true,
410 'n' => ret.non_secure = true,
411 'c' => ret.non_secure_callable = true,
412 _ => (),
413 }
414 }
415 ret
416 }
417}
418
419enum NumberBool {
420 False,
421 True,
422}
423
424impl From<NumberBool> for bool {
425 fn from(val: NumberBool) -> Self {
426 match val {
427 NumberBool::True => true,
428 NumberBool::False => false,
429 }
430 }
431}
432
433impl FromStr for NumberBool {
434 type Err = Error;
435 fn from_str(from: &str) -> Result<Self, Error> {
436 match from {
437 "true" => Ok(NumberBool::True),
438 "1" => Ok(NumberBool::True),
439 "false" => Ok(NumberBool::False),
440 "0" => Ok(NumberBool::False),
441 unknown => Err(format_err!(
442 "unkown boolean found in merory startup {}",
443 unknown
444 )),
445 }
446 }
447}
448
449#[derive(Debug, Clone, Serialize, Deserialize)]
450pub struct Memory {
451 pub p_name: Option<String>,
452 pub access: MemoryPermissions,
453 pub start: u64,
454 pub size: u64,
455 pub startup: bool,
456 pub default: bool,
457}
458
459struct MemElem(String, Memory);
460
461impl FromElem for MemElem {
462 fn from_elem(e: &Node) -> Result<Self, Error> {
463 let access = MemoryPermissions::from_str(e.attribute("access").unwrap_or_else(|| {
464 let memtype = e.attribute("id").unwrap_or_default();
465 if memtype.contains("ROM") {
466 "rx"
467 } else if memtype.contains("RAM") {
468 "rw"
469 } else {
470 ""
471 }
472 }));
473 let name = e
474 .attribute("id")
475 .or_else(|| e.attribute("name"))
476 .map(|s| s.to_string())
477 .ok_or_else(|| format_err!("No name found for memory"))?;
478 let p_name = e.attribute("Pname").map(|s| s.to_string());
479 let start = attr_parse_hex(e, "start")?;
480 let size = attr_parse_hex(e, "size")?;
481 let startup = attr_parse(e, "startup")
482 .map(|nb: NumberBool| nb.into())
483 .unwrap_or_default();
484 let default = attr_parse(e, "default")
485 .map(|nb: NumberBool| nb.into())
486 .unwrap_or_default();
487 Ok(MemElem(
488 name,
489 Memory {
490 p_name,
491 access,
492 start,
493 size,
494 startup,
495 default,
496 },
497 ))
498 }
499}
500
501#[derive(Clone, Debug, Serialize, Deserialize)]
502pub struct Memories(pub HashMap<String, Memory>);
503
504fn merge_memories(lhs: Memories, rhs: &Memories) -> Memories {
505 let rhs: Vec<_> = rhs
506 .0
507 .iter()
508 .filter_map(|(k, v)| {
509 if lhs.0.contains_key(k) {
510 None
511 } else {
512 Some((k.clone(), v.clone()))
513 }
514 })
515 .collect();
516 let mut lhs = lhs;
517 lhs.0.extend(rhs);
518 lhs
519}
520
521#[derive(Debug, Clone, Serialize, Deserialize)]
522pub enum AlgorithmStyle {
523 Keil,
524 IAR,
525 CMSIS,
526}
527
528impl FromStr for AlgorithmStyle {
529 type Err = Error;
530 fn from_str(from: &str) -> Result<Self, Error> {
531 match from {
532 "Keil" => Ok(AlgorithmStyle::Keil),
533 "IAR" => Ok(AlgorithmStyle::IAR),
534 "CMSIS" => Ok(AlgorithmStyle::CMSIS),
535 unknown => Err(format_err!("Unknown algorithm style {}", unknown)),
536 }
537 }
538}
539
540#[derive(Debug, Clone, Serialize, Deserialize)]
541pub struct Algorithm {
542 pub file_name: PathBuf,
543 pub start: u64,
544 pub size: u64,
545 pub default: bool,
546 pub ram_start: Option<u64>,
547 pub ram_size: Option<u64>,
548 pub style: AlgorithmStyle,
549}
550
551impl FromElem for Algorithm {
552 fn from_elem(e: &Node) -> Result<Self, Error> {
553 let default = attr_parse(e, "default")
554 .map(|nb: NumberBool| nb.into())
555 .unwrap_or_default();
556
557 let file_name: &str = attr_map(e, "name")?;
558 let style = attr_parse(e, "style").ok().unwrap_or(AlgorithmStyle::Keil);
559 Ok(Self {
560 file_name: file_name.replace('\\', "/").into(),
561 start: attr_parse_hex(e, "start")?,
562 size: attr_parse_hex(e, "size")?,
563 ram_start: attr_parse_hex(e, "RAMstart").ok(),
564 ram_size: attr_parse_hex(e, "RAMsize").ok(),
565 default,
566 style,
567 })
568 }
569}
570
571#[derive(Debug)]
572struct DeviceBuilder {
573 name: Option<String>,
574 algorithms: Vec<Algorithm>,
575 memories: Memories,
576 processor: Option<ProcessorsBuilder>,
577 debugs: DebugsBuilder,
578 vendor: Option<String>,
579 family: Option<String>,
580 sub_family: Option<String>,
581}
582
583#[derive(Debug, Serialize)]
584pub struct Device {
585 pub name: String,
586 pub memories: Memories,
587 pub algorithms: Vec<Algorithm>,
588 pub processors: Vec<Processor>,
589 pub vendor: Option<String>,
590 pub family: String,
591 pub sub_family: Option<String>,
592}
593
594impl DeviceBuilder {
595 fn from_elem(e: &Node) -> Self {
596 let memories = Memories(HashMap::new());
597 let mut family = None;
598 let mut sub_family = None;
599 if e.tag_name().name() == "family" {
600 family = e.attribute("Dfamily").map(|f| f.to_string());
601 }
602 if e.tag_name().name() == "subFamily" {
603 sub_family = e.attribute("DsubFamily").map(|f| f.to_string());
604 }
605
606 DeviceBuilder {
607 name: e
608 .attribute("Dname")
609 .or_else(|| e.attribute("Dvariant"))
610 .map(|f| f.to_string()),
611 vendor: e.attribute("Dvendor").map(|f| f.to_string()),
612 memories,
613 algorithms: Vec::new(),
614 processor: None,
615 debugs: DebugsBuilder(Vec::new()),
616 family,
617 sub_family,
618 }
619 }
620
621 fn build(self) -> Result<Device, Error> {
622 let name = self
623 .name
624 .ok_or_else(|| format_err!("Device found without a name"))?;
625 let family = self
626 .family
627 .ok_or_else(|| format_err!("Device found without a family"))?;
628
629 let debugs = self.debugs.build();
630
631 let processors = match self.processor {
632 Some(pb) => pb.build(debugs)?,
633 None => return Err(format_err!("Device found without a processor {}", name)),
634 };
635
636 Ok(Device {
637 processors,
638 name,
639 memories: self.memories,
640 algorithms: self.algorithms,
641 vendor: self.vendor,
642 family,
643 sub_family: self.sub_family,
644 })
645 }
646
647 fn add_parent(mut self, parent: &Self) -> Result<Self, Error> {
648 self.algorithms.extend_from_slice(&parent.algorithms);
649 Ok(Self {
650 name: self.name.or(parent.name.clone()),
651 algorithms: self.algorithms,
652 memories: merge_memories(self.memories, &parent.memories),
653 processor: match self.processor {
654 Some(old_proc) => Some(old_proc.merge(&parent.processor)?),
655 None => parent.processor.clone(),
656 },
657 debugs: self.debugs.merge(&parent.debugs),
658 vendor: self.vendor.or(parent.vendor.clone()),
659 family: self.family.or(parent.family.clone()),
660 sub_family: self.sub_family.or(parent.sub_family.clone()),
661 })
662 }
663
664 fn add_processor(&mut self, processor: ProcessorsBuilder) -> &mut Self {
665 match self.processor {
666 None => self.processor = Some(processor),
667 Some(ref mut origin) => origin.merge_into(processor),
668 };
669 self
670 }
671
672 fn add_debug(&mut self, debug: DebugsBuilder) -> &mut Self {
673 self.debugs.merge_into(debug);
674 self
675 }
676
677 fn add_memory(&mut self, MemElem(name, mem): MemElem) -> &mut Self {
678 self.memories.0.insert(name, mem);
679 self
680 }
681
682 fn add_algorithm(&mut self, alg: Algorithm) -> &mut Self {
683 self.algorithms.push(alg);
684 self
685 }
686}
687
688fn parse_device(e: &Node) -> Vec<DeviceBuilder> {
689 let mut device = DeviceBuilder::from_elem(e);
690 let variants: Vec<DeviceBuilder> = e
691 .children()
692 .filter_map(|child| match child.tag_name().name() {
693 "variant" => Some(DeviceBuilder::from_elem(&child)),
694 "memory" => {
695 FromElem::from_elem(&child)
696 .ok_warn()
697 .map(|mem| device.add_memory(mem));
698 None
699 }
700 "algorithm" => {
701 FromElem::from_elem(&child)
702 .ok_warn()
703 .map(|alg| device.add_algorithm(alg));
704 None
705 }
706 "processor" => {
707 FromElem::from_elem(&child)
708 .ok_warn()
709 .map(|prc| device.add_processor(prc));
710 None
711 }
712 "debug" => {
713 DebugsBuilder::from_elem_and_parent(&child, e)
714 .ok_warn()
715 .map(|debug| device.add_debug(debug));
716 None
717 }
718 _ => None,
719 })
720 .collect::<Vec<_>>();
721 if variants.is_empty() {
722 vec![device]
723 } else {
724 variants
725 .into_iter()
726 .flat_map(|bld| bld.add_parent(&device).ok_warn())
727 .collect()
728 }
729}
730
731fn parse_sub_family(e: &Node) -> Vec<DeviceBuilder> {
732 let mut sub_family_device = DeviceBuilder::from_elem(e);
733 let mut devices: Vec<DeviceBuilder> = Vec::new();
734
735 for child in e.children() {
736 match child.tag_name().name() {
737 "device" => {
738 devices.extend(parse_device(&child));
739 }
740 "memory" => {
741 FromElem::from_elem(&child)
742 .ok_warn()
743 .map(|mem| sub_family_device.add_memory(mem));
744 }
745 "algorithm" => {
746 FromElem::from_elem(&child)
747 .ok_warn()
748 .map(|alg| sub_family_device.add_algorithm(alg));
749 }
750 "processor" => {
751 FromElem::from_elem(&child)
752 .ok_warn()
753 .map(|prc| sub_family_device.add_processor(prc));
754 }
755 "debug" => {
756 DebugsBuilder::from_elem_and_parent(&child, e)
757 .ok_warn()
758 .map(|debug| sub_family_device.add_debug(debug));
759 }
760 _ => continue,
761 }
762 }
763 devices
764 .into_iter()
765 .flat_map(|bldr| bldr.add_parent(&sub_family_device).ok_warn())
766 .collect()
767}
768
769fn parse_family(e: &Node) -> Result<Vec<Device>, Error> {
770 let mut family_device = DeviceBuilder::from_elem(e);
771 let all_devices: Vec<DeviceBuilder> = e
772 .children()
773 .flat_map(|child| match child.tag_name().name() {
774 "subFamily" => parse_sub_family(&child),
775 "device" => parse_device(&child),
776 "memory" => {
777 FromElem::from_elem(&child)
778 .ok_warn()
779 .map(|mem| family_device.add_memory(mem));
780 Vec::new()
781 }
782 "algorithm" => {
783 FromElem::from_elem(&child)
784 .ok_warn()
785 .map(|alg| family_device.add_algorithm(alg));
786 Vec::new()
787 }
788 "processor" => {
789 FromElem::from_elem(&child)
790 .ok_warn()
791 .map(|prc| family_device.add_processor(prc));
792 Vec::new()
793 }
794 "debug" => {
795 DebugsBuilder::from_elem_and_parent(&child, e)
796 .ok_warn()
797 .map(|debug| family_device.add_debug(debug));
798 Vec::new()
799 }
800 _ => Vec::new(),
801 })
802 .collect::<Vec<_>>();
803 all_devices
804 .into_iter()
805 .map(|bldr| bldr.add_parent(&family_device).and_then(|dev| dev.build()))
806 .collect()
807}
808
809#[derive(Default, Serialize)]
810pub struct Devices(pub HashMap<String, Device>);
811
812impl FromElem for Devices {
813 fn from_elem(e: &Node) -> Result<Self, Error> {
814 e.children()
815 .try_fold(HashMap::new(), |mut res, c| {
816 let add_this = parse_family(&c)?;
817 res.extend(add_this.into_iter().map(|dev| (dev.name.clone(), dev)));
818 Ok(res)
819 })
820 .map(Devices)
821 }
822}