timetrackingstore.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // imag - the personal information management suite for the commandline
  3. // Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
  4. //
  5. // This library is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public
  7. // License as published by the Free Software Foundation; version
  8. // 2.1 of the License.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. // Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this library; if not, write to the Free Software
  17. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. //
  19. //! Extension trait for libimagstore::store::Store
  20. //!
  21. //! This module contains traits and code for extending the Store with functions that can be used to
  22. //! create, get and delete events.
  23. use chrono::NaiveDateTime as NDT;
  24. use toml::Value;
  25. use toml_query::insert::TomlValueInsertExt;
  26. use libimagstore::store::Store;
  27. use libimagstore::store::FileLockEntry;
  28. use libimagentrydatetime::datepath::compiler::DatePathCompiler;
  29. use result::Result;
  30. use constants::*;
  31. use error::TimeTrackErrorKind as TTEK;
  32. use error::MapErrInto;
  33. use iter::get::GetTimeTrackIter;
  34. use tag::TimeTrackingTag as TTT;
  35. pub trait TimeTrackStore<'a> {
  36. fn create_timetracking_now(&'a self, ts: &TTT) -> Result<FileLockEntry<'a>>;
  37. fn create_timetracking_at(&'a self, start: &NDT, ts: &TTT) -> Result<FileLockEntry<'a>>;
  38. fn create_timetracking(&'a self, start: &NDT, end: &NDT, ts: &TTT) -> Result<FileLockEntry<'a>>;
  39. fn get_timetrackings<I>(&'a self) -> Result<GetTimeTrackIter<'a>>;
  40. }
  41. fn now() -> NDT {
  42. use chrono::offset::Local;
  43. Local::now().naive_local()
  44. }
  45. lazy_static! {
  46. static ref COMPILER: DatePathCompiler = {
  47. use libimagentrydatetime::datepath::accuracy::Accuracy;
  48. use libimagentrydatetime::datepath::format::Format;
  49. DatePathCompiler::new(Accuracy::Second, Format::ElementIsFolder)
  50. };
  51. }
  52. impl<'a> TimeTrackStore<'a> for Store {
  53. fn create_timetracking_now(&'a self, ts: &TTT) -> Result<FileLockEntry<'a>> {
  54. self.create_timetracking_at(&now(), ts)
  55. }
  56. fn create_timetracking_at(&'a self, start: &NDT, ts: &TTT) -> Result<FileLockEntry<'a>> {
  57. use std::path::PathBuf;
  58. COMPILER.compile(CRATE_NAME, start)
  59. .map_err_into(TTEK::StoreIdError)
  60. .map(|mut id| {
  61. id.local_push(PathBuf::from(ts.as_str()));
  62. id
  63. })
  64. .and_then(|id| self.create(id).map_err_into(TTEK::StoreWriteError))
  65. .and_then(|mut fle| {
  66. let v = Value::String(ts.as_str().to_owned());
  67. fle.get_header_mut()
  68. .insert(DATE_TIME_TAG_HEADER_PATH, v)
  69. .map_err_into(TTEK::HeaderWriteError)
  70. .map(|_| fle)
  71. })
  72. .and_then(|mut fle| {
  73. let v = Value::String(start.format(DATE_TIME_FORMAT).to_string());
  74. fle.get_header_mut()
  75. .insert(DATE_TIME_START_HEADER_PATH, v)
  76. .map_err_into(TTEK::HeaderWriteError)
  77. .map(|_| fle)
  78. })
  79. }
  80. fn create_timetracking(&'a self, start: &NDT, end: &NDT, ts: &TTT) -> Result<FileLockEntry<'a>> {
  81. self.create_timetracking_at(start, ts)
  82. .and_then(|mut fle| {
  83. let v = Value::String(end.format(DATE_TIME_FORMAT).to_string());
  84. fle.get_header_mut()
  85. .insert(DATE_TIME_END_HEADER_PATH, v)
  86. .map_err_into(TTEK::HeaderWriteError)
  87. .map(|_| fle)
  88. })
  89. }
  90. fn get_timetrackings<I>(&'a self) -> Result<GetTimeTrackIter<'a>> {
  91. self.retrieve_for_module(CRATE_NAME)
  92. .map_err_into(TTEK::StoreReadError)
  93. .map(|iter| GetTimeTrackIter::new(iter, self))
  94. }
  95. }