cmsis_pack/pdsc/
device.rs

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                // The attributes we're interested in may be spread across multiple debug
172                // attributes defined in the family, subfamily, or device; and which may or may not
173                // be specific to a given Pname or Punit.
174                //
175                // We'll prioritize the first element with the attribute we're interested in, since
176                // family and subfamily debug elements are appended after device debug elements.
177                let debugs_iterator = debugs.iter().filter(|debug| {
178                    // If Pname or Punit are present on the <debug> element, they must match.
179                    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}