Finalize deserializing ncdu output
This commit is contained in:
parent
84a4f09fe4
commit
80bb5bbb22
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -28,6 +28,7 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_path_to_error",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -95,6 +96,16 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_path_to_error"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_repr"
|
name = "serde_repr"
|
||||||
version = "0.1.17"
|
version = "0.1.17"
|
||||||
|
@ -10,3 +10,6 @@ num-traits = "0.2.17"
|
|||||||
serde = { version = "1.0.192", features = ["derive"] }
|
serde = { version = "1.0.192", features = ["derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
serde_repr = "0.1.17"
|
serde_repr = "0.1.17"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_path_to_error = "0.1.14"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use num_traits::identities::One;
|
use num_traits::identities::One;
|
||||||
use num_traits::identities::Zero;
|
use num_traits::identities::Zero;
|
||||||
use serde::de;
|
use serde::de;
|
||||||
use serde::de::Error;
|
// use serde::de::Error;
|
||||||
use serde::de::Visitor;
|
use serde::de::Visitor;
|
||||||
use serde_repr::Deserialize_repr;
|
use serde_repr::Deserialize_repr;
|
||||||
use serde_repr::Serialize_repr;
|
use serde_repr::Serialize_repr;
|
||||||
@ -16,30 +16,26 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
// This is based on https://dev.yorhel.nl/ncdu/jsonfmt
|
// This is based on https://dev.yorhel.nl/ncdu/jsonfmt
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
#[derive(Serialize, Debug, PartialEq, Clone)]
|
||||||
struct NcduFile {
|
struct NcduFile {
|
||||||
#[serde(flatten)]
|
|
||||||
header: Header,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Debug, PartialEq, Eq, Clone)]
|
|
||||||
pub struct Header {
|
|
||||||
pub major_version: MajorVersion,
|
pub major_version: MajorVersion,
|
||||||
pub minor_version: MinorVersion,
|
pub minor_version: MinorVersion,
|
||||||
pub header_metadata: HeaderMetadata,
|
pub header_metadata: HeaderMetadata,
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub contents: Directory,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Header {
|
impl<'de> Deserialize<'de> for NcduFile {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
struct HeaderVisitor;
|
struct NcduFileVisitor;
|
||||||
impl<'de> Visitor<'de> for HeaderVisitor {
|
impl<'de> Visitor<'de> for NcduFileVisitor {
|
||||||
type Value = Header;
|
type Value = NcduFile;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
formatter.write_str("struct Header")
|
formatter.write_str("struct NcduFile")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
||||||
@ -56,25 +52,21 @@ impl<'de> Deserialize<'de> for Header {
|
|||||||
.next_element()?
|
.next_element()?
|
||||||
.ok_or_else(|| de::Error::invalid_length(2, &self))?;
|
.ok_or_else(|| de::Error::invalid_length(2, &self))?;
|
||||||
|
|
||||||
Ok(Header {
|
let contents = seq
|
||||||
|
.next_element()?
|
||||||
|
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
|
||||||
|
|
||||||
|
Ok(NcduFile {
|
||||||
major_version,
|
major_version,
|
||||||
minor_version,
|
minor_version,
|
||||||
header_metadata,
|
header_metadata,
|
||||||
|
|
||||||
|
contents,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.deserialize_seq(HeaderVisitor)
|
deserializer.deserialize_seq(NcduFileVisitor)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Header {
|
|
||||||
pub fn from(progname: String, progver: String) -> Self {
|
|
||||||
Self {
|
|
||||||
major_version: MajorVersion::default(),
|
|
||||||
minor_version: MinorVersion::default(),
|
|
||||||
header_metadata: HeaderMetadata::new(progname, progver),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +109,8 @@ pub struct HeaderMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HeaderMetadata {
|
impl HeaderMetadata {
|
||||||
fn new(progname: String, progver: String) -> Self {
|
/// Construct a HeaderMetadata with the current time
|
||||||
|
pub fn new(progname: String, progver: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
progname,
|
progname,
|
||||||
progver,
|
progver,
|
||||||
@ -142,8 +135,8 @@ impl<'de> Deserialize<'de> for Directory {
|
|||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
struct HeaderVisitor;
|
struct DirectoryVisitor;
|
||||||
impl<'de> Visitor<'de> for HeaderVisitor {
|
impl<'de> Visitor<'de> for DirectoryVisitor {
|
||||||
type Value = Directory;
|
type Value = Directory;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
@ -157,6 +150,8 @@ impl<'de> Deserialize<'de> for Directory {
|
|||||||
let info = seq
|
let info = seq
|
||||||
.next_element()?
|
.next_element()?
|
||||||
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
|
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
|
||||||
|
|
||||||
|
// TODO: Defer to vec deserialization
|
||||||
let mut contents = if let Some(size_hint) = seq.size_hint() {
|
let mut contents = if let Some(size_hint) = seq.size_hint() {
|
||||||
Vec::with_capacity(size_hint)
|
Vec::with_capacity(size_hint)
|
||||||
} else {
|
} else {
|
||||||
@ -171,7 +166,7 @@ impl<'de> Deserialize<'de> for Directory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.deserialize_seq(HeaderVisitor)
|
deserializer.deserialize_seq(DirectoryVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,26 +272,10 @@ pub struct ExtendedInfoBlock {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_header() {
|
|
||||||
let header_text = r#"[
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"progname": "Test program name",
|
|
||||||
"progver": "Version One",
|
|
||||||
"timestamp": 0
|
|
||||||
}
|
|
||||||
]"#;
|
|
||||||
|
|
||||||
let parsed = dbg!(serde_json::from_str::<Header>(header_text));
|
|
||||||
|
|
||||||
assert!(parsed.is_ok());
|
|
||||||
assert!(parsed.unwrap().minor_version == MinorVersion::Minor2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_header_metadata() {
|
fn test_header_metadata() {
|
||||||
let header_text = r#"{
|
let header_text = r#"{
|
||||||
@ -374,4 +353,24 @@ mod tests {
|
|||||||
))
|
))
|
||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use serde_path_to_error;
|
||||||
|
#[test]
|
||||||
|
fn test_simple_ncdu_output() {
|
||||||
|
let input = fs::read_to_string("../sample-ncdu-output.json").unwrap();
|
||||||
|
let jd = &mut serde_json::Deserializer::from_str(&input);
|
||||||
|
let parsed = serde_path_to_error::deserialize::<_, NcduFile>(jd)
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Error path: {:?}", e.path().to_string());
|
||||||
|
e
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
// let parsed = serde_path_to_error::from_str::<NcduFile>(&input).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(parsed.major_version, MajorVersion::Version1);
|
||||||
|
assert_eq!(parsed.minor_version, MinorVersion::Minor2);
|
||||||
|
assert_eq!(parsed.header_metadata.progname, "ncdu");
|
||||||
|
assert_eq!(parsed.contents.info.name, "/tmp/tmp.2gWrgcHU4X");
|
||||||
|
assert_eq!(parsed.contents.contents.len(), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user