dae_parser/core/
ext.rs

1use crate::*;
2
3/// Provides arbitrary additional information about or related to its parent element.
4#[derive(Clone, Default, Debug)]
5pub struct Extra {
6    /// The unique identifier of the `Extra` element.
7    /// This value must be unique within the document.
8    pub id: Option<String>,
9    /// The text string name of this element.
10    pub name: Option<String>,
11    /// A hint as to the type of information that the particular `Extra` element represents.
12    /// This text string must be understood by the application.
13    pub ty: Option<String>,
14    /// Asset management information about this element.
15    pub asset: Option<Box<Asset>>,
16    /// Declares the information used to process some portion of the content.
17    /// This field is always nonempty, because the spec provides no common data
18    /// for `Extra` elements.
19    pub technique: Vec<Technique>,
20}
21
22impl XNode for Extra {
23    const NAME: &'static str = "extra";
24    fn parse(element: &Element) -> Result<Self> {
25        debug_assert_eq!(element.name(), Self::NAME);
26        let mut it = element.children().peekable();
27        let res = Extra {
28            id: element.attr("id").map(Into::into),
29            name: element.attr("name").map(Into::into),
30            ty: element.attr("type").map(Into::into),
31            asset: Asset::parse_opt_box(&mut it)?,
32            technique: Technique::parse_list_n::<1>(&mut it)?,
33        };
34        finish(res, it)
35    }
36}
37
38impl XNodeWrite for Extra {
39    fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
40        let mut e = Self::elem();
41        e.opt_attr("id", &self.id);
42        e.opt_attr("name", &self.name);
43        e.opt_attr("type", &self.ty);
44        let e = e.start(w)?;
45        self.asset.write_to(w)?;
46        self.technique.write_to(w)?;
47        e.end(w)
48    }
49}
50
51impl Extra {
52    pub(crate) fn parse_append_many<'a>(
53        mut extras: Vec<Extra>,
54        it: impl Iterator<Item = &'a Element>,
55    ) -> Result<Vec<Extra>> {
56        for e in it {
57            match e.name() {
58                "extra" => extras.push(Extra::parse(e)?),
59                k => return Err(format!("unexpected element {}", k).into()),
60            }
61        }
62        Ok(extras)
63    }
64
65    pub(crate) fn parse_many<'a>(it: impl Iterator<Item = &'a Element>) -> Result<Vec<Extra>> {
66        Self::parse_append_many(vec![], it)
67    }
68}
69
70/// Declares the information used to process some portion of the content.
71/// Each technique conforms to an associated profile.
72/// In the COLLADA spec, this element is called "`<technique>` (core)".
73#[derive(Clone, Debug)]
74pub struct Technique {
75    /// The `<technique>` element can contain any well-formed XML data.
76    pub element: Element,
77}
78
79impl From<Element> for Technique {
80    fn from(element: Element) -> Self {
81        Self { element }
82    }
83}
84
85impl XNode for Technique {
86    const NAME: &'static str = "technique";
87    fn parse(element: &Element) -> Result<Self> {
88        debug_assert_eq!(element.name(), Self::NAME);
89        element.attr("profile").ok_or("expected 'profile' attr")?;
90        Ok(Technique {
91            element: element.clone(),
92        })
93    }
94}
95
96impl XNodeWrite for Technique {
97    fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
98        XNodeWrite::write_to(&self.element, w)
99    }
100}
101
102impl Technique {
103    /// The name of the `<technique_common>` element.
104    pub const COMMON: &'static str = "technique_common";
105}