Add database skeleton

This commit is contained in:
Anton Tarasenko 2020-11-17 19:22:12 +07:00
parent 5315a9e61b
commit 408757149c
4 changed files with 174 additions and 3 deletions

56
Cargo.lock generated
View File

@ -3,4 +3,60 @@
[[package]] [[package]]
name = "avarice" name = "avarice"
version = "0.1.0" 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"

View File

@ -7,3 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "0.4"
serde_json = "1.0"
custom_error = "1.8.0"

112
src/database/mod.rs Normal file
View File

@ -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<File>,
}
struct Category {
name: String,
groups: Vec<Group>,
}
pub struct Database {
storage: path::PathBuf,
contents: Vec<Category>,
}
impl Database {
pub fn new(storage: &path::Path) -> Result<Database, Box<dyn Error>> {
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<Category, Box<dyn Error>> {
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<Group, Box<dyn Error>> {
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()
}

View File

@ -1,13 +1,13 @@
use std::env; use std::env;
use std::path::Path; use std::path::Path;
mod unreal_config; mod database;
fn main() { fn main() {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let filename = &args[1]; let filename = &args[1];
let config = unreal_config::load_file(Path::new(filename)); let config = database::Database::new(Path::new(filename));
match config { match config {
Ok(config) => print!("{}", config), Ok(db) => print!("ok"),
_ => (), _ => (),
} }
} }