diff options
author | Lars Wirzenius <liw@liw.fi> | 2021-12-05 18:11:03 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2021-12-05 18:11:03 +0200 |
commit | 6796bdc8af51dac84f71a07198600664d2eb5e00 (patch) | |
tree | 596b0f45cb96d0cd37be50fde1bca950cff577ce | |
parent | 7ed2a28e3c7fb2e17095e63bd4153031d507cc71 (diff) | |
download | obnam-benchmark-6796bdc8af51dac84f71a07198600664d2eb5e00.tar.gz |
refactor: break out lib.rs into submodules
Sponsored-by: author
-rw-r--r-- | src/bin/obnam-benchmark.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 159 | ||||
-rw-r--r-- | src/specification.rs | 129 | ||||
-rw-r--r-- | src/step.rs | 36 |
4 files changed, 168 insertions, 158 deletions
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; @@ -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<Benchmark>, -} - -#[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<Backup>, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct Backup { - pub changes: Vec<Change>, -} - -#[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<Self, SpecificationError> { - 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<Item = &Benchmark> { - self.benchmarks.iter() - } - - pub fn steps(&self) -> Vec<Step> { - 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<Item = &Backup> { - self.backups.iter() - } -} - -impl Backup { - pub fn changes(&self) -> impl Iterator<Item = &Change> { - 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<Benchmark>, +} + +#[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<Backup>, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Backup { + pub changes: Vec<Change>, +} + +#[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<Self, SpecificationError> { + 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<Item = &Benchmark> { + self.benchmarks.iter() + } + + pub fn steps(&self) -> Vec<Step> { + 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<Item = &Backup> { + self.backups.iter() + } +} + +impl Backup { + pub fn changes(&self) -> impl Iterator<Item = &Change> { + 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(()) + } +} |