use serde::Deserialize;
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum AspaceType {
Total,
Mprotect,
Subheaps,
#[serde(other)]
Other,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Aspace {
#[serde(rename = "@type")]
pub r#type: AspaceType,
#[serde(rename = "@size")]
pub size: usize,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum SystemType {
Current,
Max,
#[serde(other)]
Other,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct System {
#[serde(rename = "@type")]
pub r#type: SystemType,
#[serde(rename = "@size")]
pub size: usize,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum TotalType {
Fast,
Rest,
Mmap,
#[serde(other)]
Other,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Total {
#[serde(rename = "@type")]
pub r#type: TotalType,
#[serde(rename = "@count")]
pub count: usize,
#[serde(rename = "@size")]
pub size: usize,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum Size {
Size {
#[serde(rename = "@from")]
from: usize,
#[serde(rename = "@to")]
to: usize,
#[serde(rename = "@total")]
total: usize,
#[serde(rename = "@count")]
count: usize,
},
Unsorted {
#[serde(rename = "@from")]
from: usize,
#[serde(rename = "@to")]
to: usize,
#[serde(rename = "@total")]
total: usize,
#[serde(rename = "@count")]
count: usize,
},
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Sizes {
#[serde(rename = "$value")]
pub sizes: Option<Vec<Size>>,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Heap {
#[serde(rename = "@nr")]
pub nr: usize,
pub sizes: Option<Sizes>,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Malloc {
#[serde(rename = "@version")]
pub version: String,
#[serde(rename = "heap")]
pub heaps: Vec<Heap>,
pub total: Vec<Total>,
pub system: Vec<System>,
pub aspace: Vec<Aspace>,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn parse_simple() {
const XML: &str = r#"
<malloc version="1">
<heap nr="0">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</heap>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</malloc>
"#;
let parsed: Malloc = quick_xml::de::from_str(XML).expect("parse XML");
assert_eq!(parsed.version, "1");
assert_eq!(parsed.heaps.len(), 1);
assert_eq!(parsed.total.len(), 2);
assert_eq!(parsed.system.len(), 2);
assert_eq!(parsed.aspace.len(), 2);
}
#[test]
fn parse_complex() {
const XML: &str = r#"
<malloc version="1">
<heap nr="0">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="1081344"/>
<system type="max" size="1081344"/>
<aspace type="total" size="1081344"/>
<aspace type="mprotect" size="1081344"/>
</heap>
<heap nr="1">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="1032192"/>
<system type="max" size="1032192"/>
<aspace type="total" size="1032192"/>
<aspace type="mprotect" size="1032192"/>
</heap>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="2113536"/>
<system type="max" size="2113536"/>
<aspace type="total" size="2113536"/>
<aspace type="mprotect" size="2113536"/>
</malloc>
"#;
let parsed: Malloc = quick_xml::de::from_str(XML).expect("parse XML");
assert_eq!(parsed.version, "1");
assert_eq!(parsed.heaps.len(), 2);
assert_eq!(parsed.total.len(), 2);
assert_eq!(parsed.system.len(), 2);
assert_eq!(parsed.aspace.len(), 2);
}
#[test]
#[should_panic]
fn parse_invalid() {
const XML: &str = r#"
<malloc version="1">
</malloc>
"#;
let _ = quick_xml::de::from_str::<Malloc>(XML).expect("parse XML");
}
}