summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..ba54da8
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,72 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Serialize, Deserialize)]
+struct Specification {
+ benchmarks: Vec<Benchmark>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct Benchmark {
+ benchmark: String,
+ backups: Vec<Backup>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct Backup {
+ changes: Vec<Change>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+enum Change {
+ Create(CreateFiles),
+ Delete(FileCount),
+ Rename(FileCount),
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct CreateFiles {
+ files: u64,
+ #[serde(with = "file_size")]
+ file_size: u64,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct FileCount {
+ files: u64,
+}
+
+fn main() {
+ let yaml = r#"
+benchmarks:
+- benchmark: foo
+ backups: []
+"#;
+ let spec: Specification = serde_yaml::from_str(yaml).unwrap();
+ serde_json::to_writer(std::io::stdout(), &spec).unwrap();
+ println!();
+}
+
+mod file_size {
+ use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
+
+ // This deserializer was originally written with u64 in mind. Then it was made generic by
+ // changing u64 to T everywhere and adding boundaries. Same with the serializer.
+ pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: std::str::FromStr,
+ <T as std::str::FromStr>::Err: std::fmt::Display,
+ {
+ String::deserialize(deserializer)?
+ .parse::<T>()
+ .map_err(|e| D::Error::custom(format!("{}", e)))
+ }
+
+ pub fn serialize<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ T: std::fmt::Display,
+ {
+ format!("{}", value).serialize(serializer)
+ }
+}