summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-10-08 19:27:37 +0200
committerMatthias Beyer <mail@beyermatthias.de>2019-10-08 19:33:35 +0200
commit0e667b788c3eeb5003d83407ef87b030874a470d (patch)
tree31148c022fde0086063a810660f37132af8d3dd8 /src
parentb8e15051ff6a845b252a8f86f8a17ccad87b4336 (diff)
Extract libical-sys wrapper library
Diffstat (limited to 'src')
-rw-r--r--src/actions/agenda.rs305
-rw-r--r--src/actions/calendars.rs25
-rw-r--r--src/actions/copy.rs45
-rw-r--r--src/actions/cursor.rs156
-rw-r--r--src/actions/delete.rs68
-rw-r--r--src/actions/edit.rs50
-rw-r--r--src/actions/gen_completions.rs35
-rw-r--r--src/actions/get.rs49
-rw-r--r--src/actions/index/action.rs182
-rw-r--r--src/actions/index/bucketable.rs162
-rw-r--r--src/actions/index/indextime.rs38
-rw-r--r--src/actions/index/mod.rs18
-rw-r--r--src/actions/list.rs32
-rw-r--r--src/actions/mod.rs16
-rw-r--r--src/actions/modify.rs140
-rw-r--r--src/actions/new.rs358
-rw-r--r--src/actions/select.rs86
-rw-r--r--src/actions/seq.rs79
-rw-r--r--src/actions/show.rs34
-rw-r--r--src/actions/undo.rs131
-rw-r--r--src/actions/unroll.rs37
-rw-r--r--src/backup.rs56
-rw-r--r--src/bin/khaleesi.rs87
-rw-r--r--src/calendars.rs33
-rw-r--r--src/cli.rs81
-rw-r--r--src/component.rs (renamed from src/icalwrap/icalcomponent.rs)3
-rw-r--r--src/config.rs131
-rw-r--r--src/cursorfile.rs92
-rw-r--r--src/defaults.rs96
-rw-r--r--src/duration.rs (renamed from src/icalwrap/icalduration.rs)0
-rw-r--r--src/edit.rs46
-rw-r--r--src/icalwrap/mod.rs26
-rw-r--r--src/input.rs71
-rw-r--r--src/khevent.rs279
-rw-r--r--src/khline.rs280
-rw-r--r--src/lib.rs66
-rw-r--r--src/macros.rs32
-rw-r--r--src/property.rs (renamed from src/icalwrap/icalproperty.rs)2
-rw-r--r--src/selectors/cal.rs76
-rw-r--r--src/selectors/daterange.rs188
-rw-r--r--src/selectors/grep.rs98
-rw-r--r--src/selectors/mod.rs142
-rw-r--r--src/selectors/prop.rs81
-rw-r--r--src/selectors/range.rs79
-rw-r--r--src/selectors/test.rs30
-rw-r--r--src/seqfile.rs72
-rw-r--r--src/testdata.rs27
-rw-r--r--src/testutils.rs15
-rw-r--r--src/time.rs (renamed from src/icalwrap/icaltime.rs)6
-rw-r--r--src/timezone.rs (renamed from src/icalwrap/icaltimezone.rs)19
-rw-r--r--src/utils/dateutil.rs4
-rw-r--r--src/utils/fileutil.rs40
-rw-r--r--src/utils/mod.rs3
-rw-r--r--src/utils/stdioutils.rs124
-rw-r--r--src/vcalendar.rs (renamed from src/icalwrap/icalvcalendar.rs)66
-rw-r--r--src/vevent.rs (renamed from src/icalwrap/icalvevent.rs)2
56 files changed, 45 insertions, 4454 deletions
diff --git a/src/actions/agenda.rs b/src/actions/agenda.rs
deleted file mode 100644
index 9659017..0000000
--- a/src/actions/agenda.rs
+++ /dev/null
@@ -1,305 +0,0 @@
-use chrono::{DateTime, Datelike, TimeZone, Local, Date};
-use yansi::{Style};
-use itertools::Itertools;
-use structopt::StructOpt;
-
-use crate::cursorfile;
-use crate::input;
-use crate::config::{Config,CalendarConfig};
-use crate::khevent::KhEvent;
-use crate::khline::KhLine;
-use crate::KhResult;
-
-#[derive(Debug, StructOpt)]
-pub struct AgendaArgs {
- /// Show agenda view
- #[structopt(name = "args")]
- pub args: Vec<String>,
-}
-
-pub fn show_events(config: &Config, args: &[&str]) -> KhResult<()> {
- let mut events = input::selection(args)?;
-
- let cursor = cursorfile::read_cursorfile().ok();
- show_events_cursor(config, &mut events, cursor.as_ref());
-
- Ok(())
-}
-
-pub fn show_events_cursor(
- config: &Config,
- events: &mut Iterator<Item = KhEvent>,
- cursor: Option<&KhLine>,
-) {
-
- let mut not_over_yet: Vec<(usize, KhEvent, Option<&CalendarConfig>)> = Vec::new();
- let mut cals_iter = events
- .enumerate()
- .map(|(i, event)| {
- let config = event.get_calendar_name().and_then(|name| config.get_config_for_calendar(&name));
- (i, event, config)
- })
- .peekable();
-
- let start_day = match cals_iter.peek() {
- Some((_, event, _)) => {
- event
- .get_start()
- .map(|dtstart| dtstart.into())
- .unwrap_or_else(|| Local.timestamp(0, 0))
- .date()
- }
- None => return,
- };
-
- let mut cur_day = start_day.pred();
- let mut last_printed_day = start_day.pred();
- while cals_iter.peek().is_some() || !not_over_yet.is_empty() {
- cur_day = cur_day.succ();
-
- maybe_print_date_line_header(&config, cur_day, start_day, &mut last_printed_day);
-
- not_over_yet.retain( |(index, event, cal_config)| {
- let is_cursor = cursor.map(|c| c.matches_khevent(&event)).unwrap_or(false);
- maybe_print_date_line(&config, cur_day, start_day, &mut last_printed_day);
- print_event_line(*cal_config, *index, &event, cur_day, is_cursor);
- event.continues_after(cur_day)
- });
-
- let relevant_events = cals_iter.peeking_take_while(|(_,event,_)| event.starts_on(cur_day));
- for (i, event, cal_config) in relevant_events {
- let is_cursor = cursor.map(|c| c.matches_khevent(&event)).unwrap_or(false);
- maybe_print_date_line(&config, cur_day, start_day, &mut last_printed_day);
- print_event_line(cal_config, i, &event, cur_day, is_cursor);
- if event.continues_after(cur_day) {
- not_over_yet.push((i, event, cal_config));
- }
- }
- }
-}
-
-fn maybe_print_week_separator(config: &Config, date: Date<Local>, start_date: Date<Local>, last_printed_date: Date<Local>) {
- if !config.agenda.print_week_separator {
- return;
- }
- if date != start_date && last_printed_date.iso_week() < date.iso_week() {
- khprintln!();
- }
-}
-
-fn maybe_print_date_line_header(config: &Config, date: Date<Local>, start_date: Date<Local>, last_printed_date: &mut Date<Local>) {
- if !config.agenda.print_empty_days {
- return;
- }
- maybe_print_date_line(config, date, start_date, last_printed_date);
-}
-
-fn maybe_print_date_line(config: &Config, date: Date<Local>, start_date: Date<Local>, last_printed_date: &mut Date<Local>) {
- if date <= *last_printed_date {
- return;
- }
- maybe_print_week_separator(config, date, start_date, *last_printed_date);
- print_date_line(date);
- *last_printed_date = date;
-}
-
-fn print_date_line(date: Date<Local>) {
- let style_heading = Style::default().bold();
- khprintln!("{}, {}", style_heading.paint(date.format("%Y-%m-%d")), date.format("%A"));
-}
-
-fn print_event_line(
- config: Option<&CalendarConfig>,
- index: usize,
- event: &KhEvent,
- date: Date<Local>,
- is_cursor: bool
-) {
- match event_line(config, &event, date, is_cursor) {
- Ok(line) => khprintln!("{:4} {}", index, line),
- Err(error) => warn!("{} in {}", error, event.get_uid())
- }
-}
-
-pub fn event_line(
- config: Option<&CalendarConfig>,
- event: &KhEvent,
- cur_day: Date<Local>,
- is_cursor: bool
-) -> Result<String, String> {
- if !event.relevant_on(cur_day) {
- return Err(format!("event is not relevant for {:?}", cur_day));
- }
-
- let mut summary = event.get_summary().ok_or("Invalid SUMMARY")?;
- if let Some(config) = config {
- let calendar_style = config.get_style_for_calendar();
- summary = calendar_style.paint(summary).to_string();
- }
-
- let cursor_icon = if is_cursor { ">" } else { "" };
-
- if event.is_allday() {
- Ok(format!("{:3} {}", cursor_icon, summary))
- } else {
- let mut time_sep = " ";
- let dtstart: DateTime<Local> = event.get_start().ok_or("Invalid DTSTART")?.into();
- let start_string = if dtstart.date() != cur_day {
- "".to_string()
- } else {
- time_sep = "-";
- format!("{}", dtstart.format("%H:%M"))
- };
-
- let dtend: DateTime<Local> = event.get_end().ok_or("Invalid DTEND")?.into();
- let end_string = if dtend.date() != cur_day {
- "".to_string()
- } else {
- time_sep = "-";
- format!("{}", dtend.format("%H:%M"))
- };
-
- Ok(format!("{:3}{:5}{}{:5} {}", cursor_icon, start_string, time_sep, end_string, summary))
- }
-}
-
-impl KhEvent {
- fn starts_on(&self, date: Date<Local>) -> bool {
- let dtstart: Date<Local> = self.get_start().unwrap().into();
- dtstart == date
- }
-
- fn relevant_on(&self, date: Date<Local>) -> bool {
- let dtstart: Option<Date<Local>> = self.get_start().map(|date| date.into());
- let last_relevant_date: Option<Date<Local>> = self.get_last_relevant_date().map(|date| date.into());
-
- dtstart.map(|dtstart| dtstart <= date).unwrap_or(false) &&
- last_relevant_date.map(|enddate| enddate >= date).unwrap_or(false)
- }
-
- fn continues_after(&self, date: Date<Local>) -> bool {
- let last_relevant_date: Option<Date<Local>> = self.get_last_relevant_date().map(|date| date.into());
- last_relevant_date
- .map(|enddate| enddate > date)
- .unwrap_or(false)
- }
-}
-
-#[cfg(test)]
-mod integration {
- use super::*;
- use crate::testdata;
- use crate::testutils::*;
- use crate::utils::stdioutils;
- use crate::config::Config;
- use crate::icalwrap::IcalVCalendar;
-
- use chrono::{Local, TimeZone};
-
- #[test]
- fn test_starts_on() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap();
- let event = cal.get_principal_khevent();
-
- let first_day = Local.ymd(2007, 6, 28);
- assert!(event.starts_on(first_day));
-
- let last_day = Local.ymd(2007, 7, 7);
- assert!(!event.starts_on(last_day));
- }
-
- #[test]
- fn test_continues_after_allday() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY_ALLDAY, None).unwrap();
- let event = cal.get_principal_khevent();
- let first_day = Local.ymd(2007, 6, 28);
- assert!(event.continues_after(first_day));
- let last_day = Local.ymd(2007, 7, 8);
- assert!(!event.continues_after(last_day));
- }
-
- #[test]
- fn test_continues_after_simple() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_ONE_MEETING, None).unwrap();
- let event = cal.get_principal_khevent();
- let date = Local.ymd(1997, 3, 24);
- assert!(!event.continues_after(date));
- }
-
- #[test]
- fn test_event_line_negative() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_ONE_MEETING, None).unwrap();
- let event = cal.get_principal_khevent();
- let date = Local.ymd(1998, 1, 1);
- let event_line = event_line(None, &event, date, false);
- assert!(event_line.is_err())
- }
-
- #[test]
- fn test_event_line_simple() {
- testdata::setup();
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_ONE_MEETING, None).unwrap();
- let event = cal.get_principal_khevent();
- let date = Local.ymd(1997, 3, 24);
- let event_line = event_line(None, &event, date, false).unwrap();
- assert_eq!(" 13:30-22:00 Calendaring Interoperability Planning Meeting".to_string(), event_line)
- }
-
- #[test]
- fn test_event_line_cursor() {
- testdata::setup();
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_ONE_MEETING, None).unwrap();
- let event = cal.get_principal_khevent();
- let date = Local.ymd(1997, 3, 24);
- let event_line = event_line(None, &event, date, true).unwrap();
- assert_eq!("> 13:30-22:00 Calendaring Interoperability Planning Meeting".to_string(), event_line)
- }
-
- #[test]
- fn test_event_line_multiday() {
- testdata::setup();
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap();
- let event = cal.get_principal_khevent();
- let begin = Local.ymd(2007, 6, 28);
- let middle = Local.ymd(2007, 6, 30);
- let end = Local.ymd(2007, 7, 9);
- let event_line_begin = event_line(None, &event, begin, false).unwrap();
- let event_line_middle = event_line(None, &event, middle, false).unwrap();
- let event_line_end = event_line(None, &event, end, false).unwrap();
- assert_eq!(" 15:29- Festival International de Jazz de Montreal".to_string(), event_line_begin);
- assert_eq!(" Festival International de Jazz de Montreal".to_string(), event_line_middle);
- assert_eq!(" -09:29 Festival International de Jazz de Montreal".to_string(), event_line_end);
- }
-
- #[test]
- fn test_event_line_multiday_allday() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY_ALLDAY, None).unwrap();
- let event = cal.get_principal_khevent();
- let date = Local.ymd(2007, 6, 28);
- let event_line = event_line(None, &event, date, false).unwrap();
- assert_eq!(" Festival International de Jazz de Montreal".to_string(), event_line)
- }
-
- #[test]
- fn test_stdout_simple() {
- testdata::setup();
- let _testdir = prepare_testdir("testdir_with_seq");
-
- show_events(&Config::read_config(), &[]).unwrap();
-
- let stdout = stdioutils::test_stdout_clear();
- let expected = indoc!("
- 2018-12-13, Thursday
- 0 23:30- shows up on two days
- 2018-12-14, Friday
- 0 shows up on two days
- 2018-12-15, Saturday
- 0 shows up on two days
- 2018-12-16, Sunday
- 0 shows up on two days
- 2018-12-17, Monday
- 0 -19:30 shows up on two days
- ");
- assert_eq!(expected, stdout);
- }
-}
diff --git a/src/actions/calendars.rs b/src/actions/calendars.rs
deleted file mode 100644
index 72a8a7d..0000000
--- a/src/actions/calendars.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use calendars;
-
-pub fn action_list_calendars(_args: &[String]) -> Result<(), String> {
- for calendar in calendars::calendar_list() {
- khprintln!("{}", calendar);
- }
-
- Ok(())
-}
-
-#[cfg(test)]
-mod integration {
- use super::*;
-
- use testutils;
-
- #[test]
- fn test() {
- let _testdir = testutils::prepare_testdir("testdir_two_cals");
-
- action_list_calendars(&[]).unwrap();
-
- assert_eq!("second\nsecond/second_sub\nfirst\n", testutils::test_stdout_clear());
- }
-}
diff --git a/src/actions/copy.rs b/src/actions/copy.rs
deleted file mode 100644
index 811bcc5..0000000
--- a/src/actions/copy.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use crate::input;
-use crate::utils::fileutil;
-use crate::utils::misc;
-
-use crate::KhResult;
-
-pub fn do_copy() -> KhResult<()> {
- let khline = input::default_input_khline()?;
-
- let uid = &misc::make_new_uid();
- let cal = khline.to_cal()?;
- let new_cal = cal.with_uid(uid)?.with_dtstamp_now();
-
- fileutil::write_cal(&new_cal)?;
-
- info!("Successfully wrote file: {}", new_cal.get_path().unwrap().display());
-
- Ok(())
-}
-
-
-#[cfg(test)]
-mod integration {
- use super::*;
-
- use assert_fs::prelude::*;
- use crate::khline::KhLine;
- use crate::testutils::prepare_testdir;
- use crate::utils::stdioutils;
- use predicates::prelude::*;
-
- #[test]
- fn copy_test() {
- let testdir = prepare_testdir("testdir");
- stdioutils::test_stdin_write("twodaysacrossbuckets.ics");
-
- do_copy().unwrap();
-
- let child = testdir.child(".khaleesi/cal/11111111-2222-3333-4444-444444444444@khaleesi.ics");
- child.assert(predicate::path::exists());
-
- let khline = "11111111-2222-3333-4444-444444444444@khaleesi.ics".parse::<KhLine>().unwrap();
- assert_eq!("11111111-2222-3333-4444-444444444444@khaleesi", khline.to_event().unwrap().get_uid());
- }
-}
diff --git a/src/actions/cursor.rs b/src/actions/cursor.rs
deleted file mode 100644
index b15ffed..0000000
--- a/src/actions/cursor.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-use crate::cursorfile;
-use crate::utils::stdioutils;
-use crate::KhResult;
-use crate::seqfile;
-
-use structopt::StructOpt;
-
-#[derive(Debug, StructOpt)]
-pub struct CursorArgs {
- /// Move the cursor on the selection.
- #[structopt(name = "direction", raw(possible_values = "&CursorDirection::variants()"))]
- pub direction: Option<CursorDirection>,
-}
-
-arg_enum! {
-#[derive(Debug)]
- pub enum CursorDirection {
- Next,
- Prev,
- }
-}
-
-enum Direction {
- Up,
- Down,
-}
-
-pub fn do_cursor(args: &CursorArgs) -> KhResult<()> {
- if !stdioutils::is_stdin_tty() {
- write_stdin_to_cursorfile()?;
- } else {
- //println!("stdin is tty")
- if let Some(direction) = &args.direction {
- match direction {
- CursorDirection::Prev => return cursor_sequence_move(&Direction::Up),
- CursorDirection::Next => return cursor_sequence_move(&Direction::Down),
- }
- };
- }
-
- if !stdioutils::is_stdout_tty() || stdioutils::is_stdin_tty() {
- write_cursorfile_to_stdout();
- }
-
- Ok(())
-}
-
-fn write_stdin_to_cursorfile() -> KhResult<()> {
- let lines = stdioutils::read_lines_from_stdin()?;
-
- if lines.len() > 1 {
- Err("Too many lines on stdin")?;
- };
-
- cursorfile::write_cursorfile(&lines[0])?;
-
- Ok(())
-}
-
-fn write_cursorfile_to_stdout() {
- if let Ok(cursor) = cursorfile::read_cursorfile() {
- khprintln!("{}", cursor);
- }
-}
-
-fn cursor_sequence_move(direction: &Direction) -> KhResult<()> {
- let cursor_event = cursorfile::read_cursorfile()?;
- let mut seq = seqfile::read_seqfile_khlines()?;
- let next_elem = match direction {
- Direction::Up => {
- let mut seq_rev = seq.rev();
- seq_rev.find(|line| line == &cursor_event);
- seq_rev.next()
- },
- Direction::Down => {
- seq.find(|line| line == &cursor_event);
- seq.next()
- }
- };
-
- match next_elem {
- Some(next_elem) => cursorfile::write_cursorfile(&next_elem.to_string()),
- None => {
- warn!("Already at end of sequence");
- Ok(())
- }
- }
-}
-
-#[cfg(test)]
-mod integration {
- use super::*;
-
- use crate::testutils;
- use assert_fs::prelude::*;
- use predicates::prelude::*;
-
- #[test]
- fn test_with_stdin() {
- let testdir = testutils::prepare_testdir_empty();
- let expected_str = "hi there";
- stdioutils::test_stdin_write(expected_str);
-
- let args = CursorArgs{direction: None};
- do_cursor(&args).unwrap();
-
- testdir.child(".khaleesi/cursor").assert(expected_str);
- }
-
- #[test]
- fn test_cursor_sequence_move_next() {
- let testdir = testutils::prepare_testdir("testdir_with_seq_and_cursor");
- let args = CursorArgs{direction: Some(CursorDirection::Next)};
- do_cursor(&args).unwrap();
-
- let out = "1182988800 rfc_multi_day_allday.ics";
- let predicate = predicate::str::similar(out);
- testdir.child(".khaleesi/cursor").assert(predicate);
- }
-
- #[test]
- fn test_cursor_sequence_move_prev_at_end() {
- let testdir = testutils::prepare_testdir("testdir_with_seq_and_cursor");
- let args = CursorArgs{direction: Some(CursorDirection::Prev)};
- do_cursor(&args).unwrap();
-
- let out = "1544740200 twodaysacrossbuckets.ics\n";
- let predicate = predicate::str::similar(out);
- testdir.child(".khaleesi/cursor").assert(predicate);
- }
-
- #[test]
- fn test_with_stdin_linebreak() {
- let _testdir = testutils::prepare_testdir_empty();
- let expected_str = "hi\nthere";
- stdioutils::test_stdin_write(expected_str);
-
- let args = CursorArgs {direction: None};
- let result = do_cursor(&args);
-
- assert!(result.is_err());
- //testdir.child(".khaleesi/cursor").assert(expected_str);
- }
-
- #[test]
- fn test_no_stdin() {
- let testdir = testutils::prepare_testdir("testdir_with_cursor");
-
- let args = CursorArgs {direction: None};
- do_cursor(&args).unwrap();
- let out = stdioutils::test_stdout_clear();
-
- let predicate = predicate::str::similar(out);
- testdir.child(".khaleesi/cursor").assert(predicate);
- }
-}
diff --git a/src/actions/delete.rs b/src/actions/delete.rs
deleted file mode 100644
index ac2065a..0000000
--- a/src/actions/delete.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-use crate::input;
-use crate::backup::backup;
-use crate::KhResult;
-use crate::khline::KhLine;
-use crate::utils::stdioutils;
-
-use std::path::PathBuf;
-use std::fs::remove_file;
-
-pub fn do_delete() -> KhResult<()> {
- info!("do_delete");
-
- let cursor_khline = input::default_input_khline()?;
-
- delete_file(cursor_khline)
-}
-
-fn delete_file(khline: KhLine) -> KhResult<()> {
-
- if ask_really_delete(&khline.path) {
- let backup_path = backup(&khline).unwrap();
- info!("Backup written to {}", backup_path.display());
-
- remove_file(khline.path.clone())?;
- info!("deleted {:#?}", khline.get_normalized_path());
- }
-
- Ok(())
-}
-
-fn ask_really_delete(path: &PathBuf) -> bool {
- if cfg!(test) { return true };
-
- println!("Really delete {:#?}? y/n:", path);
-
- match stdioutils::read_single_char_from_stdin().unwrap() {
- 'y' => true,
- _ => false
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use crate::testutils::*;
- use assert_fs::prelude::*;
- use predicates::prelude::*;
-
- #[test]
- fn test_do_delete_cursor() {
- let testdir = prepare_testdir("testdir_with_cursor");
-
- do_delete().unwrap();
-
- let predicate = predicate::path::missing();
- testdir.child(".khaleesi/cal/twodaysacrossbuckets").assert(predicate);
-
- }
-
- #[test]
- #[should_panic]
- fn test_do_delete_no_cursor() {
- let _testdir = prepare_testdir("testdir");
-
- do_delete().unwrap();
- }
-}
diff --git a/src/actions/edit.rs b/src/actions/edit.rs
deleted file mode 100644
index 9d1abf8..0000000
--- a/src/actions/edit.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use tempfile::NamedTempFile;
-
-use crate::backup::backup;
-use crate::edit;
-use crate::input;
-use crate::khline::KhLine;
-use crate::utils::fileutil;
-use crate::KhResult;
-
-pub fn do_edit() -> KhResult<()> {
- let khline = input::default_input_khline()?;
- edit(&khline)
-}
-
-fn edit(khline: &KhLine) -> KhResult<()> {
- let tempfile = NamedTempFile::new()?;
- let calendar = khline.to_cal()?;
-
- fileutil::write_file(tempfile.path(), &calendar.to_string())?;
- edit::edit_loop(&tempfile.path())?;
-
- let backup_path = backup(&khline).unwrap();
- info!("Backup written to {}", backup_path.display());
-
- let edited_cal = KhLine::new(tempfile.path(), None).to_cal()?.with_dtstamp_now().with_last_modified_now();
- fileutil::write_file(&khline.path, &edited_cal.to_string())?;
- info!("Successfully edited file {}", khline.path.display());
-
- Ok(())
-}
-
-#[cfg(test)]
-mod integration {
- use super::*;
-
- use crate::testutils::prepare_testdir;
-
- #[test]
- fn edit_test() {
- let _testdir = prepare_testdir("testdir");
-
- let khline = "twodaysacrossbuckets.ics".parse::<KhLine>().unwrap();
-
- assert!(edit(&khline).is_ok());
- let event = khline.to_event().unwrap();
-
- assert_eq!("20130101T010203Z", event.get_dtstamp().unwrap());
- assert_eq!("20130101T010203Z", event.get_last_modified().unwrap());
- }
-}
diff --git a/src/actions/gen_completions.rs b/src/actions/gen_completions.rs
deleted file mode 100644
index e8e11ca..0000000
--- a/src/actions/gen_completions.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use std::io;
-use structopt::clap::Shell;
-use structopt::StructOpt;
-
-use crate::cli::CommandLine;
-use crate::KhResult;
-
-#[derive(Debug, StructOpt)]
-pub struct GenCompletionsArgs {
- /// the shell
- #[structopt(name = "shell", raw(possible_values = "&ShellArg::variants()"))]
- pub shell: ShellArg,
-}
-
-arg_enum! {
-#[derive(Debug)]
- pub enum ShellArg{
- Bash,
- Zsh,
- Fish,
- Elvish
- }