From 6796bdc8af51dac84f71a07198600664d2eb5e00 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 5 Dec 2021 18:11:03 +0200 Subject: refactor: break out lib.rs into submodules Sponsored-by: author --- src/bin/obnam-benchmark.rs | 2 +- src/lib.rs | 159 +-------------------------------------------- src/specification.rs | 129 ++++++++++++++++++++++++++++++++++++ src/step.rs | 36 ++++++++++ 4 files changed, 168 insertions(+), 158 deletions(-) create mode 100644 src/specification.rs create mode 100644 src/step.rs diff --git a/src/bin/obnam-benchmark.rs b/src/bin/obnam-benchmark.rs index b36565e..4d4bcf3 100644 --- a/src/bin/obnam-benchmark.rs +++ b/src/bin/obnam-benchmark.rs @@ -1,4 +1,4 @@ -use obnam_benchmark::Specification; +use obnam_benchmark::specification::Specification; use std::fs::File; use std::path::PathBuf; use std::process::exit; diff --git a/src/lib.rs b/src/lib.rs index 85c6941..dda1212 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,157 +1,2 @@ -use serde::{Deserialize, Serialize}; -use std::fs::File; -use std::path::{Path, PathBuf}; -use std::collections::HashSet; - -#[derive(Debug, Serialize, Deserialize)] -#[serde(deny_unknown_fields)] -pub struct Specification { - benchmarks: Vec, -} - -#[derive(Debug, thiserror::Error)] -pub enum SpecificationError { - #[error("Duplicate benchmark name {0}")] - DuplicateBenchmark(String), - - #[error("Couldn't open {0}: {1}")] - Open(PathBuf, std::io::Error), - - #[error("Couldn't read YAML specification from {0}:\n {1}")] - Yaml(PathBuf, serde_yaml::Error), -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct Benchmark { - benchmark: String, - backups: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct Backup { - pub changes: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum Change { - #[serde(rename = "create")] - Create(Create), - - #[serde(rename = "delete")] - Delete(FileCount), - - #[serde(rename = "rename")] - Rename(FileCount), -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Create { - files: u64, - file_size: u64, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct FileCount { - files: u64, -} - -#[derive(Debug)] -pub enum Step { - Start(String), - Stop(String), - MeasureChunks, - Create(Create), - Rename(FileCount), - Delete(FileCount), - Backup(usize), - Restore(usize), -} - -impl Specification { - pub fn from_file(filename: &Path) -> Result { - let f = File::open(filename) - .map_err(|err| SpecificationError::Open(filename.to_path_buf(), err))?; - let spec: Specification = serde_yaml::from_reader(f) - .map_err(|err| SpecificationError::Yaml(filename.to_path_buf(), err))?; - spec.check()?; - Ok(spec) - } - - fn check(&self) -> Result<(), SpecificationError> { - let mut names = HashSet::new(); - for name in self.benchmarks().map(|b| b.name()) { - let name = name.to_string(); - if names.contains(&name) { - return Err(SpecificationError::DuplicateBenchmark(name)); - } - names.insert(name); - } - Ok(()) - } - - pub fn benchmarks(&self) -> impl Iterator { - self.benchmarks.iter() - } - - pub fn steps(&self) -> Vec { - let mut steps = vec![]; - for b in self.benchmarks() { - steps.push(Step::Start(b.name().to_string())); - for (i, backup) in b.backups().enumerate() { - for change in backup.changes() { - steps.push(Step::from(change)); - } - steps.push(Step::Backup(i)); - } - for (i, _) in b.backups().enumerate() { - steps.push(Step::Restore(i)); - } - steps.push(Step::Stop(b.name().to_string())); - } - steps - } -} - -impl Benchmark { - pub fn name(&self) -> &str { - &self.benchmark - } - - pub fn backups(&self) -> impl Iterator { - self.backups.iter() - } -} - -impl Backup { - pub fn changes(&self) -> impl Iterator { - self.changes.iter() - } -} - -impl Change { - pub fn execute(&self) -> Result<(), SpecificationError> { - match self { - Change::Create(x) => println!("create {} {}", x.files, x.file_size), - Change::Rename(x) => println!("rename {}", x.files), - Change::Delete(x) => println!("delete {}", x.files), - } - Ok(()) - } -} - -impl Step { - pub fn from(change: &Change) -> Self { - match change { - Change::Create(x) => Self::Create(x.clone()), - Change::Rename(x) => Self::Rename(x.clone()), - Change::Delete(x) => Self::Delete(x.clone()), - } - } - - pub fn execute(&self) -> Result<(), SpecificationError> { - println!("execute {:?}", self); - let t = std::time::Duration::from_millis(1000); - std::thread::sleep(t); - Ok(()) - } -} +pub mod specification; +pub mod step; diff --git a/src/specification.rs b/src/specification.rs new file mode 100644 index 0000000..e4b20d1 --- /dev/null +++ b/src/specification.rs @@ -0,0 +1,129 @@ +use crate::step::Step; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +use std::fs::File; +use std::path::{Path, PathBuf}; + +#[derive(Debug, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct Specification { + benchmarks: Vec, +} + +#[derive(Debug, thiserror::Error)] +pub enum SpecificationError { + #[error("Duplicate benchmark name {0}")] + DuplicateBenchmark(String), + + #[error("Couldn't open {0}: {1}")] + Open(PathBuf, std::io::Error), + + #[error("Couldn't read YAML specification from {0}:\n {1}")] + Yaml(PathBuf, serde_yaml::Error), +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Benchmark { + benchmark: String, + backups: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Backup { + pub changes: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Change { + #[serde(rename = "create")] + Create(Create), + + #[serde(rename = "delete")] + Delete(FileCount), + + #[serde(rename = "rename")] + Rename(FileCount), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Create { + files: u64, + file_size: u64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct FileCount { + files: u64, +} + +impl Specification { + pub fn from_file(filename: &Path) -> Result { + let f = File::open(filename) + .map_err(|err| SpecificationError::Open(filename.to_path_buf(), err))?; + let spec: Specification = serde_yaml::from_reader(f) + .map_err(|err| SpecificationError::Yaml(filename.to_path_buf(), err))?; + spec.check()?; + Ok(spec) + } + + fn check(&self) -> Result<(), SpecificationError> { + let mut names = HashSet::new(); + for name in self.benchmarks().map(|b| b.name()) { + let name = name.to_string(); + if names.contains(&name) { + return Err(SpecificationError::DuplicateBenchmark(name)); + } + names.insert(name); + } + Ok(()) + } + + pub fn benchmarks(&self) -> impl Iterator { + self.benchmarks.iter() + } + + pub fn steps(&self) -> Vec { + let mut steps = vec![]; + for b in self.benchmarks() { + steps.push(Step::Start(b.name().to_string())); + for (i, backup) in b.backups().enumerate() { + for change in backup.changes() { + steps.push(Step::from(change)); + } + steps.push(Step::Backup(i)); + } + for (i, _) in b.backups().enumerate() { + steps.push(Step::Restore(i)); + } + steps.push(Step::Stop(b.name().to_string())); + } + steps + } +} + +impl Benchmark { + pub fn name(&self) -> &str { + &self.benchmark + } + + pub fn backups(&self) -> impl Iterator { + self.backups.iter() + } +} + +impl Backup { + pub fn changes(&self) -> impl Iterator { + self.changes.iter() + } +} + +impl Change { + pub fn execute(&self) -> Result<(), SpecificationError> { + match self { + Change::Create(x) => println!("create {} {}", x.files, x.file_size), + Change::Rename(x) => println!("rename {}", x.files), + Change::Delete(x) => println!("delete {}", x.files), + } + Ok(()) + } +} diff --git a/src/step.rs b/src/step.rs new file mode 100644 index 0000000..a3a208a --- /dev/null +++ b/src/step.rs @@ -0,0 +1,36 @@ +use crate::specification::{Change, Create, FileCount}; + +#[derive(Debug)] +pub enum Step { + Start(String), + Stop(String), + MeasureChunks, + Create(Create), + Rename(FileCount), + Delete(FileCount), + Backup(usize), + Restore(usize), +} + +#[derive(Debug, thiserror::Error)] +pub enum StepError { + #[error(transparent)] + Io(std::io::Error), +} + +impl Step { + pub fn from(change: &Change) -> Self { + match change { + Change::Create(x) => Self::Create(x.clone()), + Change::Rename(x) => Self::Rename(x.clone()), + Change::Delete(x) => Self::Delete(x.clone()), + } + } + + pub fn execute(&self) -> Result<(), StepError> { + println!("execute {:?}", self); + let t = std::time::Duration::from_millis(1000); + std::thread::sleep(t); + Ok(()) + } +} -- cgit v1.2.1