diff --git a/dblib/src/err.rs b/dblib/src/err.rs new file mode 100644 index 0000000..e065e71 --- /dev/null +++ b/dblib/src/err.rs @@ -0,0 +1,4 @@ +use std::error::Error; +pub type Result = ::std::result::Result>; + + diff --git a/dblib/src/keystore.rs b/dblib/src/keystore.rs new file mode 100644 index 0000000..1e154b6 --- /dev/null +++ b/dblib/src/keystore.rs @@ -0,0 +1,67 @@ +use std::collections::HashMap; +use std::fs::File; +use std::io::BufReader; +use std::io::BufWriter; +use crate::{err, DB, dev_urandom, KeyStore}; +use crate::ApiKey; + +impl KeyStore for DB { + fn new_entry(filename: String, name: String) -> err::Result { + //! Create a new API key entry in the data-store given by + //! Key value is generated via /dev/urandom on unix systems + let file = File::open(filename.as_str())?; + let reader = BufReader::new(file); + + let mut data: DB = serde_json::from_reader(reader)?; + // Generate some new key data + let key = dev_urandom().unwrap(); // create a new key + let entry = ApiKey { key: key.clone(), name }; + + // Finally write back the data to the structure and disk + data.keys.push(entry); + let file = File::open(filename.as_str())?; + let writer = BufWriter::new(file); + serde_json::to_writer(writer, &data)?; + + Ok(key) + } + + fn remove_entry(filename: String, name: String) -> err::Result { + //! Removes the API key entry based on the given name + let file = File::open(filename.as_str())?; + let reader = BufReader::new(file); + + let mut data: DB = serde_json::from_reader(reader)?; + let idx = data.keys.iter().position(|item| item.name == name); + if let Some(idx) = idx { + data.keys.remove(idx); + Ok(true) + } else { + Ok(false) + } + } + + fn get_entry(filename: String, name: String) -> err::Result> { + //! Get the API key based on name + let file = File::open(filename.as_str())?; + let reader = BufReader::new(file); + + let data: DB = serde_json::from_reader(reader)?; + // WARNING: extreme autism + match data.keys.iter().find(|item| item.name == name) { + Some(item) => Ok(Some(item.key.clone())), + None => Ok(None) + } + } + + fn new_store(filename: String) -> err::Result<()> { + //! Generate a new empty data store with the given filename + //! NOTE: The filename must include the extension(programmatically) + let file = File::create(filename)?; + let empty = DB { keys: vec![] , videos: HashMap::new() }; + let writer = BufWriter::new(file); + serde_json::to_writer(writer, &empty)?; + Ok(()) + } +} + diff --git a/dblib/src/lib.rs b/dblib/src/lib.rs index 75a8b8e..ba3c3a6 100644 --- a/dblib/src/lib.rs +++ b/dblib/src/lib.rs @@ -1,12 +1,12 @@ -use std::error::Error; +use std::collections::HashMap; use std::fs::File; -use std::io::BufReader; -use std::io::BufWriter; use std::io::prelude::*; use serde::{Serialize, Deserialize}; pub mod request; +pub mod keystore; +pub mod err; use request::ApiKey; fn dev_urandom() -> std::io::Result { @@ -23,69 +23,31 @@ fn dev_urandom() -> std::io::Result { return Ok(output); } +#[derive(Serialize, Deserialize)] +pub struct VideoMeta { + pub id: u64, + pub string: String, + pub desc: Option +} #[derive(Serialize, Deserialize)] pub struct DB { - keys: Vec + keys: Vec, + videos: HashMap } - -impl DB { - pub fn new_entry(filename: String, name: String) -> Result> { - //! Create a new API key entry in the data-store given by - //! Key value is generated via /dev/urandom on unix systems - let file = File::open(filename.as_str())?; - let reader = BufReader::new(file); - - let mut data: DB = serde_json::from_reader(reader)?; - // Generate some new key data - let key = dev_urandom().unwrap(); // create a new key - let entry = ApiKey { key: key.clone(), name }; - - // Finally write back the data to the structure and disk - data.keys.push(entry); - let file = File::open(filename.as_str())?; - let writer = BufWriter::new(file); - serde_json::to_writer(writer, &data)?; - - Ok(key) - } - - pub fn remove_entry(filename: String, name: String) -> Result> { - //! Removes the API key entry based on the given name - let file = File::open(filename.as_str())?; - let reader = BufReader::new(file); - - let mut data: DB = serde_json::from_reader(reader)?; - let idx = data.keys.iter().position(|item| item.name == name); - if let Some(idx) = idx { - data.keys.remove(idx); - Ok(true) - } else { - Ok(false) - } - } - - pub fn get_entry(filename: String, name: String) -> Result, Box> { - //! Get the API key based on name - let file = File::open(filename.as_str())?; - let reader = BufReader::new(file); - - let data: DB = serde_json::from_reader(reader)?; - // WARNING: extreme autism - match data.keys.iter().find(|item| item.name == name) { - Some(item) => Ok(Some(item.key.clone())), - None => Ok(None) - } - } - - pub fn new_store(filename: String) -> Result<(), Box> { - //! Generate a new empty data store with the given filename - //! NOTE: The filename must include the extension(programmatically) - let file = File::create(filename)?; - let empty = DB { keys: vec![] }; - let writer = BufWriter::new(file); - serde_json::to_writer(writer, &empty)?; - Ok(()) - } +// TODO: add some proper lifetime management here and some docs +pub trait KeyStore { + fn new_entry(filename: String, name: String) -> err::Result; + fn remove_entry(filename: String, name: String) -> err::Result; + fn get_entry(filename: String, name: String) -> err::Result>; + fn new_store(filename: String) -> err::Result<()>; +} + +pub trait VideoStore { + fn new_video(name: &str, desc: &str) -> err::Result<()>; + fn del_video(id: u64) -> err::Result<()>; + fn get_video(id: Option, name: Option<&str>) -> err::Result; + fn rename_video(id: u64, new: &str) -> err::Result<()>; + fn redescribe_video(id: u64, new: &str) -> err::Result<()>; } diff --git a/dblib/src/request.rs b/dblib/src/request.rs index 60f9f75..194dbc4 100644 --- a/dblib/src/request.rs +++ b/dblib/src/request.rs @@ -1,5 +1,6 @@ use std::env; use crate::DB; +use crate::KeyStore; use rocket::request::{self, Request, FromRequest}; use rocket::http::Status;