Merge pull request #1065 from matthiasbeyer/libimagnotes/do-not-wrap
libimagnotes: Do not wrap store types.
This commit is contained in:
commit
be8a3d1242
8 changed files with 264 additions and 196 deletions
|
@ -28,18 +28,18 @@ extern crate libimagentryedit;
|
||||||
extern crate libimagerror;
|
extern crate libimagerror;
|
||||||
extern crate libimagutil;
|
extern crate libimagutil;
|
||||||
|
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use libimagentryedit::edit::Edit;
|
use libimagentryedit::edit::Edit;
|
||||||
use libimagrt::runtime::Runtime;
|
use libimagrt::runtime::Runtime;
|
||||||
use libimagrt::setup::generate_runtime_setup;
|
use libimagrt::setup::generate_runtime_setup;
|
||||||
use libimagnotes::note::Note;
|
use libimagnotes::note::Note;
|
||||||
use libimagerror::trace::{MapErrTrace, trace_error};
|
use libimagnotes::notestore::*;
|
||||||
|
use libimagerror::trace::MapErrTrace;
|
||||||
use libimagutil::info_result::*;
|
use libimagutil::info_result::*;
|
||||||
use libimagutil::warn_result::WarnResult;
|
use libimagutil::warn_result::WarnResult;
|
||||||
|
|
||||||
|
|
||||||
mod ui;
|
mod ui;
|
||||||
use ui::build_ui;
|
use ui::build_ui;
|
||||||
|
|
||||||
|
@ -71,49 +71,54 @@ fn name_from_cli(rt: &Runtime, subcmd: &str) -> String {
|
||||||
|
|
||||||
fn create(rt: &Runtime) {
|
fn create(rt: &Runtime) {
|
||||||
let name = name_from_cli(rt, "create");
|
let name = name_from_cli(rt, "create");
|
||||||
Note::new(rt.store(), name.clone(), String::new()).map_err_trace().ok();
|
let mut note = rt
|
||||||
|
.store()
|
||||||
|
.new_note(name.clone(), String::new())
|
||||||
|
.map_err_trace_exit(1)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if rt.cli().subcommand_matches("create").unwrap().is_present("edit") &&
|
if rt.cli().subcommand_matches("create").unwrap().is_present("edit") {
|
||||||
!edit_entry(rt, name) {
|
let _ = note
|
||||||
exit(1);
|
.edit_content(rt)
|
||||||
|
.map_warn_err_str("Editing failed")
|
||||||
|
.map_err_trace_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(rt: &Runtime) {
|
fn delete(rt: &Runtime) {
|
||||||
Note::delete(rt.store(), String::from(name_from_cli(rt, "delete")))
|
let _ = rt.store()
|
||||||
.map_err_trace()
|
.delete_note(name_from_cli(rt, "delete"))
|
||||||
.map_info_str("Ok")
|
.map_info_str("Ok")
|
||||||
.ok();
|
.map_err_trace_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit(rt: &Runtime) {
|
fn edit(rt: &Runtime) {
|
||||||
edit_entry(rt, name_from_cli(rt, "edit"));
|
let name = name_from_cli(rt, "edit");
|
||||||
}
|
let _ = rt
|
||||||
|
.store()
|
||||||
fn edit_entry(rt: &Runtime, name: String) -> bool {
|
.get_note(name.clone())
|
||||||
let mut note = match Note::get(rt.store(), name) {
|
.map_err_trace_exit(1)
|
||||||
Ok(Some(note)) => note,
|
.unwrap()
|
||||||
Ok(None) => {
|
.map(|mut note| {
|
||||||
warn!("Cannot edit nonexistent Note");
|
let _ = note
|
||||||
return false
|
.edit_content(rt)
|
||||||
},
|
.map_warn_err_str("Editing failed")
|
||||||
Err(e) => {
|
.map_err_trace_exit(1);
|
||||||
trace_error(&e);
|
})
|
||||||
warn!("Cannot edit nonexistent Note");
|
.unwrap_or_else(|| {
|
||||||
return false
|
error!("Cannot find note with name '{}'", name);
|
||||||
},
|
});
|
||||||
};
|
|
||||||
|
|
||||||
note.edit_content(rt).map_err_trace().map_warn_err_str("Editing failed").is_ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(rt: &Runtime) {
|
fn list(rt: &Runtime) {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
Note::all_notes(rt.store())
|
rt.store()
|
||||||
|
.all_notes()
|
||||||
.map_err_trace_exit(1)
|
.map_err_trace_exit(1)
|
||||||
.map(|iter| {
|
.map(|iter| {
|
||||||
let notes = iter.filter_map(|note| note.map_err_trace().ok())
|
let notes = iter
|
||||||
|
.filter_map(|noteid| rt.store().get(noteid).map_err_trace_exit(1).unwrap())
|
||||||
.sorted_by(|note_a, note_b| {
|
.sorted_by(|note_a, note_b| {
|
||||||
if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
|
if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
|
||||||
return a.cmp(&b)
|
return a.cmp(&b)
|
||||||
|
|
|
@ -58,6 +58,8 @@ This section contains the changelog from the last release to the next release.
|
||||||
* The "toml-query" dependency was updated to 0.3.1
|
* The "toml-query" dependency was updated to 0.3.1
|
||||||
* `imag-timetrack track` is now able to parse "now", date-only start/stop
|
* `imag-timetrack track` is now able to parse "now", date-only start/stop
|
||||||
dates and date-time start/stop times.
|
dates and date-time start/stop times.
|
||||||
|
* `libimagnotes` does not longer wrap store types but extend them.
|
||||||
|
|
||||||
* Stats
|
* Stats
|
||||||
|
|
||||||
## 0.3.0
|
## 0.3.0
|
||||||
|
|
50
lib/domain/libimagnotes/src/iter.rs
Normal file
50
lib/domain/libimagnotes/src/iter.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
//
|
||||||
|
// imag - the personal information management suite for the commandline
|
||||||
|
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; version
|
||||||
|
// 2.1 of the License.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
|
||||||
|
use libimagstore::storeid::StoreId;
|
||||||
|
use libimagstore::storeid::StoreIdIterator;
|
||||||
|
|
||||||
|
use notestoreid::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NoteIterator(StoreIdIterator);
|
||||||
|
|
||||||
|
impl NoteIterator {
|
||||||
|
|
||||||
|
pub fn new(iditer: StoreIdIterator) -> NoteIterator {
|
||||||
|
NoteIterator(iditer)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for NoteIterator {
|
||||||
|
type Item = StoreId;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
while let Some(n) = self.0.next() {
|
||||||
|
if n.is_note_id() {
|
||||||
|
return Some(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -49,4 +49,7 @@ module_entry_path_mod!("notes");
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod note;
|
pub mod note;
|
||||||
|
pub mod notestore;
|
||||||
|
pub mod notestoreid;
|
||||||
|
pub mod iter;
|
||||||
|
|
||||||
|
|
|
@ -17,80 +17,36 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
//
|
//
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use toml::Value;
|
use toml::Value;
|
||||||
|
|
||||||
use libimagrt::runtime::Runtime;
|
use libimagstore::store::Entry;
|
||||||
use libimagentryedit::edit::Edit;
|
|
||||||
use libimagentryedit::error::Result as EditResult;
|
|
||||||
use libimagstore::storeid::IntoStoreId;
|
|
||||||
use libimagstore::storeid::StoreId;
|
|
||||||
use libimagstore::storeid::StoreIdIterator;
|
|
||||||
use libimagstore::store::FileLockEntry;
|
|
||||||
use libimagstore::store::Store;
|
|
||||||
|
|
||||||
use toml_query::read::TomlValueReadExt;
|
use toml_query::read::TomlValueReadExt;
|
||||||
use toml_query::set::TomlValueSetExt;
|
use toml_query::set::TomlValueSetExt;
|
||||||
|
|
||||||
use module_path::ModuleEntryPath;
|
|
||||||
use error::Result;
|
use error::Result;
|
||||||
use error::NoteErrorKind as NEK;
|
use error::NoteErrorKind as NEK;
|
||||||
use error::NoteError as NE;
|
use error::NoteError as NE;
|
||||||
use error::ResultExt;
|
use error::ResultExt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub trait Note {
|
||||||
pub struct Note<'a> {
|
fn set_name(&mut self, n: String) -> Result<()>;
|
||||||
entry: FileLockEntry<'a>,
|
fn get_name(&self) -> Result<String>;
|
||||||
|
fn set_text(&mut self, n: String);
|
||||||
|
fn get_text(&self) -> &String;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Note<'a> {
|
impl Note for Entry {
|
||||||
|
|
||||||
pub fn new(store: &Store, name: String, text: String) -> Result<Note> {
|
fn set_name(&mut self, n: String) -> Result<()> {
|
||||||
use std::ops::DerefMut;
|
self.get_header_mut()
|
||||||
|
|
||||||
debug!("Creating new Note: '{}'", name);
|
|
||||||
let fle = {
|
|
||||||
let mut lockentry = try!(ModuleEntryPath::new(name.clone())
|
|
||||||
.into_storeid()
|
|
||||||
.and_then(|id| store.create(id))
|
|
||||||
.chain_err(|| NEK::StoreWriteError));
|
|
||||||
|
|
||||||
{
|
|
||||||
let entry = lockentry.deref_mut();
|
|
||||||
|
|
||||||
{
|
|
||||||
let header = entry.get_header_mut();
|
|
||||||
let _ = header
|
|
||||||
.set("note", Value::Table(BTreeMap::new()))
|
|
||||||
.chain_err(|| NEK::StoreWriteError);
|
|
||||||
|
|
||||||
let _ = header
|
|
||||||
.set("note.name", Value::String(name))
|
|
||||||
.chain_err(|| NEK::StoreWriteError);
|
|
||||||
}
|
|
||||||
|
|
||||||
*entry.get_content_mut() = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
lockentry
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Note { entry: fle })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_name(&mut self, n: String) -> Result<()> {
|
|
||||||
self.entry
|
|
||||||
.get_header_mut()
|
|
||||||
.set("note.name", Value::String(n))
|
.set("note.name", Value::String(n))
|
||||||
.chain_err(|| NEK::StoreWriteError)
|
.chain_err(|| NEK::StoreWriteError)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_name(&self) -> Result<String> {
|
fn get_name(&self) -> Result<String> {
|
||||||
let header = self.entry.get_header();
|
match self.get_header().read("note.name") {
|
||||||
match header.read("note.name") {
|
|
||||||
Ok(Some(&Value::String(ref s))) => Ok(s.clone()),
|
Ok(Some(&Value::String(ref s))) => Ok(s.clone()),
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
Err(NE::from_kind(NEK::HeaderTypeError)).chain_err(|| NEK::StoreReadError)
|
Err(NE::from_kind(NEK::HeaderTypeError)).chain_err(|| NEK::StoreReadError)
|
||||||
|
@ -99,104 +55,14 @@ impl<'a> Note<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&mut self, n: String) {
|
fn set_text(&mut self, n: String) {
|
||||||
*self.entry.get_content_mut() = n
|
*self.get_content_mut() = n
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_text(&self) -> &String {
|
fn get_text(&self) -> &String {
|
||||||
self.entry.get_content()
|
self.get_content()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(store: &Store, name: String) -> Result<()> {
|
|
||||||
ModuleEntryPath::new(name)
|
|
||||||
.into_storeid()
|
|
||||||
.and_then(|id| store.delete(id))
|
|
||||||
.chain_err(|| NEK::StoreWriteError)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn retrieve(store: &Store, name: String) -> Result<Note> {
|
|
||||||
ModuleEntryPath::new(name)
|
|
||||||
.into_storeid()
|
|
||||||
.and_then(|id| store.retrieve(id))
|
|
||||||
.chain_err(|| NEK::StoreWriteError)
|
|
||||||
.map(|entry| Note { entry: entry })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(store: &Store, name: String) -> Result<Option<Note>> {
|
|
||||||
ModuleEntryPath::new(name)
|
|
||||||
.into_storeid()
|
|
||||||
.and_then(|id| store.get(id))
|
|
||||||
.chain_err(|| NEK::StoreWriteError)
|
|
||||||
.map(|o| o.map(|entry| Note { entry: entry }))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn all_notes(store: &Store) -> Result<NoteIterator> {
|
|
||||||
store.retrieve_for_module("notes")
|
|
||||||
.map(|iter| NoteIterator::new(store, iter))
|
|
||||||
.chain_err(|| NEK::StoreReadError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Edit for Note<'a> {
|
|
||||||
|
|
||||||
fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> {
|
|
||||||
self.entry.edit_content(rt)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait FromStoreId {
|
|
||||||
fn from_storeid(&Store, StoreId) -> Result<Note>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> FromStoreId for Note<'a> {
|
|
||||||
|
|
||||||
fn from_storeid(store: &Store, id: StoreId) -> Result<Note> {
|
|
||||||
debug!("Loading note from storeid: '{:?}'", id);
|
|
||||||
match store.retrieve(id) {
|
|
||||||
Err(e) => Err(e).chain_err(|| NEK::StoreReadError),
|
|
||||||
Ok(entry) => Ok(Note { entry: entry }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Deref for Note<'a> {
|
|
||||||
|
|
||||||
type Target = FileLockEntry<'a>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &FileLockEntry<'a> {
|
|
||||||
&self.entry
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct NoteIterator<'a> {
|
|
||||||
store: &'a Store,
|
|
||||||
iditer: StoreIdIterator,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> NoteIterator<'a> {
|
|
||||||
|
|
||||||
pub fn new(store: &'a Store, iditer: StoreIdIterator) -> NoteIterator<'a> {
|
|
||||||
NoteIterator {
|
|
||||||
store: store,
|
|
||||||
iditer: iditer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for NoteIterator<'a> {
|
|
||||||
type Item = Result<Note<'a>>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<Note<'a>>> {
|
|
||||||
self.iditer
|
|
||||||
.next()
|
|
||||||
.map(|id| Note::from_storeid(self.store, id))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
108
lib/domain/libimagnotes/src/notestore.rs
Normal file
108
lib/domain/libimagnotes/src/notestore.rs
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
//
|
||||||
|
// imag - the personal information management suite for the commandline
|
||||||
|
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; version
|
||||||
|
// 2.1 of the License.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use toml::Value;
|
||||||
|
|
||||||
|
use libimagstore::storeid::IntoStoreId;
|
||||||
|
use libimagstore::store::FileLockEntry;
|
||||||
|
use libimagstore::store::Store;
|
||||||
|
|
||||||
|
use toml_query::set::TomlValueSetExt;
|
||||||
|
|
||||||
|
use module_path::ModuleEntryPath;
|
||||||
|
use error::Result;
|
||||||
|
use error::NoteErrorKind as NEK;
|
||||||
|
use error::ResultExt;
|
||||||
|
use iter::*;
|
||||||
|
|
||||||
|
pub trait NoteStore<'a> {
|
||||||
|
fn new_note(&'a self, name: String, text: String) -> Result<FileLockEntry<'a>>;
|
||||||
|
fn delete_note(&'a self, name: String) -> Result<()>;
|
||||||
|
fn retrieve_note(&'a self, name: String) -> Result<FileLockEntry<'a>>;
|
||||||
|
fn get_note(&'a self, name: String) -> Result<Option<FileLockEntry<'a>>>;
|
||||||
|
fn all_notes(&'a self) -> Result<NoteIterator>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a> NoteStore<'a> for Store {
|
||||||
|
|
||||||
|
fn new_note(&'a self, name: String, text: String) -> Result<FileLockEntry<'a>> {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
debug!("Creating new Note: '{}'", name);
|
||||||
|
let fle = {
|
||||||
|
let mut lockentry = try!(ModuleEntryPath::new(name.clone())
|
||||||
|
.into_storeid()
|
||||||
|
.and_then(|id| self.create(id))
|
||||||
|
.chain_err(|| NEK::StoreWriteError));
|
||||||
|
|
||||||
|
{
|
||||||
|
let entry = lockentry.deref_mut();
|
||||||
|
|
||||||
|
{
|
||||||
|
let header = entry.get_header_mut();
|
||||||
|
let _ = header
|
||||||
|
.set("note", Value::Table(BTreeMap::new()))
|
||||||
|
.chain_err(|| NEK::StoreWriteError);
|
||||||
|
|
||||||
|
let _ = header
|
||||||
|
.set("note.name", Value::String(name))
|
||||||
|
.chain_err(|| NEK::StoreWriteError);
|
||||||
|
}
|
||||||
|
|
||||||
|
*entry.get_content_mut() = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
lockentry
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(fle)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_note(&'a self, name: String) -> Result<()> {
|
||||||
|
ModuleEntryPath::new(name)
|
||||||
|
.into_storeid()
|
||||||
|
.and_then(|id| self.delete(id))
|
||||||
|
.chain_err(|| NEK::StoreWriteError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retrieve_note(&'a self, name: String) -> Result<FileLockEntry<'a>> {
|
||||||
|
ModuleEntryPath::new(name)
|
||||||
|
.into_storeid()
|
||||||
|
.and_then(|id| self.retrieve(id))
|
||||||
|
.chain_err(|| NEK::StoreWriteError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_note(&'a self, name: String) -> Result<Option<FileLockEntry<'a>>> {
|
||||||
|
ModuleEntryPath::new(name)
|
||||||
|
.into_storeid()
|
||||||
|
.and_then(|id| self.get(id))
|
||||||
|
.chain_err(|| NEK::StoreWriteError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn all_notes(&'a self) -> Result<NoteIterator> {
|
||||||
|
self.retrieve_for_module("notes")
|
||||||
|
.map(NoteIterator::new)
|
||||||
|
.chain_err(|| NEK::StoreReadError)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
32
lib/domain/libimagnotes/src/notestoreid.rs
Normal file
32
lib/domain/libimagnotes/src/notestoreid.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// imag - the personal information management suite for the commandline
|
||||||
|
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; version
|
||||||
|
// 2.1 of the License.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
|
||||||
|
use libimagstore::storeid::StoreId;
|
||||||
|
|
||||||
|
pub trait NoteStoreId {
|
||||||
|
fn is_note_id(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NoteStoreId for StoreId {
|
||||||
|
fn is_note_id(&self) -> bool {
|
||||||
|
self.is_in_collection(&["notes"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
use libimagstore::store::Entry;
|
use libimagstore::store::Entry;
|
||||||
use libimagstore::store::Store;
|
use libimagstore::store::Store;
|
||||||
use libimagentrylink::internal::InternalLinker;
|
use libimagentrylink::internal::InternalLinker;
|
||||||
use libimagnotes::note::Note;
|
use libimagnotes::notestore::NoteStore;
|
||||||
use libimagnotes::note::NoteIterator;
|
use libimagnotes::iter::NoteIterator;
|
||||||
use libimagstore::storeid::StoreIdIterator;
|
use libimagstore::storeid::StoreIdIterator;
|
||||||
|
|
||||||
use error::Result;
|
use error::Result;
|
||||||
|
@ -43,8 +43,8 @@ impl<'a> AnnotationFetcher<'a> for Store {
|
||||||
/// Wrapper around `Note::all_notes()` of `libimagnotes` which filters out normal notes and
|
/// Wrapper around `Note::all_notes()` of `libimagnotes` which filters out normal notes and
|
||||||
/// leaves only annotations in the iterator.
|
/// leaves only annotations in the iterator.
|
||||||
fn all_annotations(&'a self) -> Result<AnnotationIter<'a>> {
|
fn all_annotations(&'a self) -> Result<AnnotationIter<'a>> {
|
||||||
Note::all_notes(self)
|
NoteStore::all_notes(self)
|
||||||
.map(|iter| AnnotationIter::new(iter))
|
.map(|iter| AnnotationIter::new(iter, self))
|
||||||
.chain_err(|| AEK::StoreReadError)
|
.chain_err(|| AEK::StoreReadError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ impl<'a> AnnotationFetcher<'a> for Store {
|
||||||
entry.get_internal_links()
|
entry.get_internal_links()
|
||||||
.chain_err(|| AEK::StoreReadError)
|
.chain_err(|| AEK::StoreReadError)
|
||||||
.map(|iter| StoreIdIterator::new(Box::new(iter.map(|e| e.get_store_id().clone()))))
|
.map(|iter| StoreIdIterator::new(Box::new(iter.map(|e| e.get_store_id().clone()))))
|
||||||
.map(|iter| NoteIterator::new(self, iter))
|
.map(NoteIterator::new)
|
||||||
.map(|iter| AnnotationIter::new(iter))
|
.map(|i| AnnotationIter::new(i, self))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,9 @@ pub mod iter {
|
||||||
|
|
||||||
use toml_query::read::TomlValueReadExt;
|
use toml_query::read::TomlValueReadExt;
|
||||||
|
|
||||||
use libimagnotes::note::Note;
|
use libimagnotes::iter::NoteIterator;
|
||||||
use libimagnotes::note::NoteIterator;
|
use libimagstore::store::Store;
|
||||||
|
use libimagstore::store::FileLockEntry;
|
||||||
|
|
||||||
use error::Result;
|
use error::Result;
|
||||||
use error::AnnotationErrorKind as AEK;
|
use error::AnnotationErrorKind as AEK;
|
||||||
|
@ -79,23 +80,23 @@ pub mod iter {
|
||||||
use error::ResultExt;
|
use error::ResultExt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AnnotationIter<'a>(NoteIterator<'a>);
|
pub struct AnnotationIter<'a>(NoteIterator, &'a Store);
|
||||||
|
|
||||||
impl<'a> AnnotationIter<'a> {
|
impl<'a> AnnotationIter<'a> {
|
||||||
|
|
||||||
pub fn new(noteiter: NoteIterator<'a>) -> AnnotationIter<'a> {
|
pub fn new(noteiter: NoteIterator, store: &'a Store) -> AnnotationIter<'a> {
|
||||||
AnnotationIter(noteiter)
|
AnnotationIter(noteiter, store)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for AnnotationIter<'a> {
|
impl<'a> Iterator for AnnotationIter<'a> {
|
||||||
type Item = Result<Note<'a>>;
|
type Item = Result<FileLockEntry<'a>>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<Note<'a>>> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
loop {
|
loop {
|
||||||
match self.0.next() {
|
match self.0.next().map(|id| self.1.get(id)) {
|
||||||
Some(Ok(note)) => {
|
Some(Ok(Some(note))) => {
|
||||||
match note.get_header().read("annotation.is_annotation") {
|
match note.get_header().read("annotation.is_annotation") {
|
||||||
Ok(None) => continue, // not an annotation
|
Ok(None) => continue, // not an annotation
|
||||||
Ok(Some(&Value::Boolean(true))) => return Some(Ok(note)),
|
Ok(Some(&Value::Boolean(true))) => return Some(Ok(note)),
|
||||||
|
@ -103,8 +104,9 @@ pub mod iter {
|
||||||
Err(e) => return Some(Err(e).chain_err(|| AEK::HeaderReadError)),
|
Err(e) => return Some(Err(e).chain_err(|| AEK::HeaderReadError)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(Err(e)) => return Some(Err(e).chain_err(|| AEK::StoreReadError)),
|
Some(Ok(None)) => continue,
|
||||||
None => return None, // iterator consumed
|
Some(Err(e)) => return Some(Err(e).chain_err(|| AEK::StoreReadError)),
|
||||||
|
None => return None, // iterator consumed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue