Add initial structure

This commit is contained in:
Matthias Beyer 2016-02-13 18:29:34 +01:00
parent d21e11e3a5
commit 41bb6d6f53
4 changed files with 214 additions and 1 deletions

88
libimagnotes/src/error.rs Normal file
View file

@ -0,0 +1,88 @@
use std::error::Error;
use std::fmt::Error as FmtError;
use std::clone::Clone;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;
use std::convert::From;
/**
* Kind of error
*/
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum NoteErrorKind {
StoreWriteError,
StoreReadError,
HeaderTypeError,
NoteToEntryConversion,
// Nothing here yet
}
fn note_error_type_as_str(e: &NoteErrorKind) -> &'static str {
match e {
&NoteErrorKind::StoreWriteError => "Error writing store",
&NoteErrorKind::StoreReadError => "Error reading store",
&NoteErrorKind::HeaderTypeError => "Header type error",
&NoteErrorKind::NoteToEntryConversion => "Error converting Note instance to Entry instance",
}
}
impl Display for NoteErrorKind {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
try!(write!(fmt, "{}", note_error_type_as_str(self)));
Ok(())
}
}
/**
* Store error type
*/
#[derive(Debug)]
pub struct NoteError {
err_type: NoteErrorKind,
cause: Option<Box<Error>>,
}
impl NoteError {
/**
* Build a new NoteError from an NoteErrorKind, optionally with cause
*/
pub fn new(errtype: NoteErrorKind, cause: Option<Box<Error>>) -> NoteError {
NoteError {
err_type: errtype,
cause: cause,
}
}
/**
* Get the error type of this NoteError
*/
pub fn err_type(&self) -> NoteErrorKind {
self.err_type.clone()
}
}
impl Display for NoteError {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
try!(write!(fmt, "[{}]", note_error_type_as_str(&self.err_type.clone())));
Ok(())
}
}
impl Error for NoteError {
fn description(&self) -> &str {
note_error_type_as_str(&self.err_type.clone())
}
fn cause(&self) -> Option<&Error> {
self.cause.as_ref().map(|e| &**e)
}
}

View file

@ -3,6 +3,12 @@ extern crate semver;
extern crate toml; extern crate toml;
extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; #[macro_use] extern crate libimagstore;
extern crate libimagtag; extern crate libimagtag;
module_entry_path_mod!("notes", "0.1.0");
pub mod error;
pub mod note;
pub mod result;

113
libimagnotes/src/note.rs Normal file
View file

@ -0,0 +1,113 @@
use std::convert::Into;
use std::collections::BTreeMap;
use std::ops::{DerefMut, Deref};
use toml::Value;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagtag::tag::Tag;
use libimagtag::tagable::Tagable;
use libimagtag::result::Result as TagResult;
use libimagtag::error::{TagError, TagErrorKind};
use module_path::ModuleEntryPath;
use result::Result;
use error::NoteError as NE;
use error::NoteErrorKind as NEK;
pub struct Note<'a> {
entry: FileLockEntry<'a>,
}
impl<'a> Note<'a> {
pub fn new(store: &Store, name: String, text: String) -> Result<Note> {
use std::ops::DerefMut;
debug!("Creating new Note: '{}'", name);
let fle = {
let mut lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
if lockentry.is_err() {
return Err(NE::new(NEK::StoreWriteError, Some(Box::new(lockentry.err().unwrap()))));
}
let mut lockentry = lockentry.unwrap();
{
let mut entry = lockentry.deref_mut();
let mut header = entry.get_header_mut();
let setres = header.set("note", Value::Table(BTreeMap::new()));
if setres.is_err() {
return Err(NE::new(NEK::StoreWriteError, Some(Box::new(setres.err().unwrap()))));
}
let setres = header.set("note.name", Value::String(name));
if setres.is_err() {
return Err(NE::new(NEK::StoreWriteError, Some(Box::new(setres.err().unwrap()))));
}
}
lockentry
};
Ok(Note { entry: fle })
}
pub fn set_name(&mut self, n: String) -> Result<()> {
let mut header = self.entry.deref_mut().get_header_mut();
header.set("note.name", Value::String(n))
.map_err(|e| NE::new(NEK::StoreWriteError, Some(Box::new(e))))
.map(|_| ())
}
pub fn get_name(&self) -> Result<String> {
let mut header = self.entry.deref().get_header();
match header.read("note.name") {
Ok(Some(Value::String(s))) => Ok(String::from(s)),
Ok(_) => {
let e = NE::new(NEK::HeaderTypeError, None);
Err(NE::new(NEK::StoreReadError, Some(Box::new(e))))
},
Err(e) => Err(NE::new(NEK::StoreReadError, Some(Box::new(e))))
}
}
pub fn set_text(&mut self, n: String) {
*self.entry.deref_mut().get_content_mut() = n
}
pub fn get_text(&self) -> &String {
self.entry.deref().get_content()
}
}
impl<'a> Tagable for Note<'a> {
fn get_tags(&self) -> TagResult<Vec<Tag>> {
self.entry.deref().get_tags()
}
fn set_tags(&mut self, ts: Vec<Tag>) -> TagResult<()> {
self.entry.deref_mut().set_tags(ts)
}
fn add_tag(&mut self, t: Tag) -> TagResult<()> {
self.entry.deref_mut().add_tag(t)
}
fn remove_tag(&mut self, t: Tag) -> TagResult<()> {
self.entry.deref_mut().remove_tag(t)
}
fn has_tag(&self, t: &Tag) -> TagResult<bool> {
self.entry.deref().has_tag(t)
}
fn has_tags(&self, ts: &Vec<Tag>) -> TagResult<bool> {
self.entry.deref().has_tags(ts)
}
}

View file

@ -0,0 +1,6 @@
use std::result::Result as RResult;
use error::NoteError;
pub type Result<T> = RResult<T, NoteError>;