From 408757149c8f31b7e09da3043fcd08d481eeb633 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Tue, 17 Nov 2020 19:22:12 +0700 Subject: [PATCH] Add database skeleton --- Cargo.lock | 56 ++++++++++++++++++++++ Cargo.toml | 3 ++ src/database/mod.rs | 112 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 6 +-- 4 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/database/mod.rs diff --git a/Cargo.lock b/Cargo.lock index b0eb9bf..ba42506 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,4 +3,60 @@ [[package]] name = "avarice" version = "0.1.0" +dependencies = [ + "custom_error 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", +] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "custom_error" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_json" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum custom_error 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51ac5e99a7fea3ee8a03fa4721a47e2efd3fbb38358fc61192a54d4c6f866c12" +"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +"checksum serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +"checksum serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" diff --git a/Cargo.toml b/Cargo.toml index e8facc0..e04d62e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +log = "0.4" +serde_json = "1.0" +custom_error = "1.8.0" \ No newline at end of file diff --git a/src/database/mod.rs b/src/database/mod.rs new file mode 100644 index 0000000..19f78fa --- /dev/null +++ b/src/database/mod.rs @@ -0,0 +1,112 @@ +use log::warn; +use serde_json; +use std::error::Error; +use std::fs; +use std::path; + +extern crate custom_error; +use custom_error::custom_error; + +custom_error! {DatabaseError + NotDirectory{path: String} = "Path to database should point at the directory: {path}", +} + +struct File { + name: String, + contents: serde_json::Value, +} + +struct Group { + name: String, + files: Vec, +} + +struct Category { + name: String, + groups: Vec, +} + +pub struct Database { + storage: path::PathBuf, + contents: Vec, +} + +impl Database { + pub fn new(storage: &path::Path) -> Result> { + if !storage.is_dir() { + return Err(Box::new(DatabaseError::NotDirectory { + path: storage.display().to_string(), + })); + } + let mut contents = Vec::new(); + for entry in fs::read_dir(storage)? { + let entry = entry?; + let path = entry.path(); + if !path.is_dir() { + warn!( + r#"File {} found where only category directories are supposed to be"#, + path.display() + ); + } else { + let category = load_category(&path)?; + contents.push(category); + } + } + Ok(Database { + storage: storage.to_path_buf(), + contents, + }) + } +} + +fn load_category(category_path: &path::Path) -> Result> { + let mut groups = Vec::new(); + for entry in fs::read_dir(category_path)? { + let entry = entry?; + let path = entry.path(); + if !path.is_dir() { + warn!( + r#"File {} found where only group directories are supposed to be"#, + path.display() + ); + } else { + let group = load_group(&path)?; + groups.push(group); + } + } + Ok(Category { + name: get_file_name(category_path), + groups, + }) +} + +fn load_group(group_path: &path::Path) -> Result> { + let mut files = Vec::new(); + for entry in fs::read_dir(group_path)? { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + warn!( + r#"Directory {} found where only data files are supposed to be"#, + path.display() + ); + } else { + let file_contents = fs::read_to_string(&path)?; + files.push(File { + name: get_file_name(path.as_path()), + contents: serde_json::from_str(&file_contents)?, + }); + } + } + Ok(Group { + name: get_file_name(group_path), + files, + }) +} + +fn get_file_name(path: &path::Path) -> String { + path.file_stem() + .and_then(|x| x.to_str()) + .unwrap_or_default() + .to_string() +} diff --git a/src/main.rs b/src/main.rs index 8f664c9..b78fc6d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,13 @@ use std::env; use std::path::Path; -mod unreal_config; +mod database; fn main() { let args: Vec = env::args().collect(); let filename = &args[1]; - let config = unreal_config::load_file(Path::new(filename)); + let config = database::Database::new(Path::new(filename)); match config { - Ok(config) => print!("{}", config), + Ok(db) => print!("ok"), _ => (), } }