diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2019-10-08 19:27:37 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2019-10-08 19:33:35 +0200 |
commit | 0e667b788c3eeb5003d83407ef87b030874a470d (patch) | |
tree | 31148c022fde0086063a810660f37132af8d3dd8 /src | |
parent | b8e15051ff6a845b252a8f86f8a17ccad87b4336 (diff) |
Extract libical-sys wrapper library
Diffstat (limited to 'src')
-rw-r--r-- | src/actions/agenda.rs | 305 | ||||
-rw-r--r-- | src/actions/calendars.rs | 25 | ||||
-rw-r--r-- | src/actions/copy.rs | 45 | ||||
-rw-r--r-- | src/actions/cursor.rs | 156 | ||||
-rw-r--r-- | src/actions/delete.rs | 68 | ||||
-rw-r--r-- | src/actions/edit.rs | 50 | ||||
-rw-r--r-- | src/actions/gen_completions.rs | 35 | ||||
-rw-r--r-- | src/actions/get.rs | 49 | ||||
-rw-r--r-- | src/actions/index/action.rs | 182 | ||||
-rw-r--r-- | src/actions/index/bucketable.rs | 162 | ||||
-rw-r--r-- | src/actions/index/indextime.rs | 38 | ||||
-rw-r--r-- | src/actions/index/mod.rs | 18 | ||||
-rw-r--r-- | src/actions/list.rs | 32 | ||||
-rw-r--r-- | src/actions/mod.rs | 16 | ||||
-rw-r--r-- | src/actions/modify.rs | 140 | ||||
-rw-r--r-- | src/actions/new.rs | 358 | ||||
-rw-r--r-- | src/actions/select.rs | 86 | ||||
-rw-r--r-- | src/actions/seq.rs | 79 | ||||
-rw-r--r-- | src/actions/show.rs | 34 | ||||
-rw-r--r-- | src/actions/undo.rs | 131 | ||||
-rw-r--r-- | src/actions/unroll.rs | 37 | ||||
-rw-r--r-- | src/backup.rs | 56 | ||||
-rw-r--r-- | src/bin/khaleesi.rs | 87 | ||||
-rw-r--r-- | src/calendars.rs | 33 | ||||
-rw-r--r-- | src/cli.rs | 81 | ||||
-rw-r--r-- | src/component.rs (renamed from src/icalwrap/icalcomponent.rs) | 3 | ||||
-rw-r--r-- | src/config.rs | 131 | ||||
-rw-r--r-- | src/cursorfile.rs | 92 | ||||
-rw-r--r-- | src/defaults.rs | 96 | ||||
-rw-r--r-- | src/duration.rs (renamed from src/icalwrap/icalduration.rs) | 0 | ||||
-rw-r--r-- | src/edit.rs | 46 | ||||
-rw-r--r-- | src/icalwrap/mod.rs | 26 | ||||
-rw-r--r-- | src/input.rs | 71 | ||||
-rw-r--r-- | src/khevent.rs | 279 | ||||
-rw-r--r-- | src/khline.rs | 280 | ||||
-rw-r--r-- | src/lib.rs | 66 | ||||
-rw-r--r-- | src/macros.rs | 32 | ||||
-rw-r--r-- | src/property.rs (renamed from src/icalwrap/icalproperty.rs) | 2 | ||||
-rw-r--r-- | src/selectors/cal.rs | 76 | ||||
-rw-r--r-- | src/selectors/daterange.rs | 188 | ||||
-rw-r--r-- | src/selectors/grep.rs | 98 | ||||
-rw-r--r-- | src/selectors/mod.rs | 142 | ||||
-rw-r--r-- | src/selectors/prop.rs | 81 | ||||
-rw-r--r-- | src/selectors/range.rs | 79 | ||||
-rw-r--r-- | src/selectors/test.rs | 30 | ||||
-rw-r--r-- | src/seqfile.rs | 72 | ||||
-rw-r--r-- | src/testdata.rs | 27 | ||||
-rw-r--r-- | src/testutils.rs | 15 | ||||
-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.rs | 4 | ||||
-rw-r--r-- | src/utils/fileutil.rs | 40 | ||||
-rw-r--r-- | src/utils/mod.rs | 3 | ||||
-rw-r--r-- | src/utils/stdioutils.rs | 124 | ||||
-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 - } |