diff options
author | Nora <nora.widdecke@tu-bs.de> | 2019-01-20 13:24:13 +0100 |
---|---|---|
committer | Nora <nora.widdecke@tu-bs.de> | 2019-01-20 16:29:27 +0100 |
commit | d6195b29fa8a7369cfa47b288f55efa8ad4d656d (patch) | |
tree | 62381cbf6b818f82e97b4156630a908f07e040ff /src/edit.rs | |
parent | 16f95ae751e3c96f3f4f335139ab07ab8234f1e6 (diff) |
edit: refactor for legibility
Diffstat (limited to 'src/edit.rs')
-rw-r--r-- | src/edit.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/edit.rs b/src/edit.rs new file mode 100644 index 0000000..549b7b7 --- /dev/null +++ b/src/edit.rs @@ -0,0 +1,88 @@ +use std::env; +use std::fs; +use std::path::Path; +use std::process::Command; +use tempfile::NamedTempFile; + +use backup::backup; +use khline::KhLine; +use utils::fileutil; +use KhResult; + +pub fn edit(khline: &KhLine) -> KhResult<()> { + let tempfile = NamedTempFile::new()?; + let calendar = khline.to_cal()?; + + fileutil::write_file(tempfile.path(), &calendar.to_string())?; + 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(()) +} + +fn edit_loop(path: &Path) -> KhResult<()> { + loop { + edit_file(path)?; + let edited_cal = KhLine::new(path, None).to_cal()?; + if let Some(errors) = edited_cal.check_for_errors() { + if !ask_continue_editing(&errors) { + return Err("editing aborted by user")?; + } + } else { + return Ok(()); + } + } +} + +fn edit_file(path: &Path) -> KhResult<()> { + if cfg!(test) { return Ok(()) }; + + let editor = env::var("EDITOR").unwrap_or_else(|_| "vim".to_string()); + + Command::new(&editor) + .arg(path.as_os_str()) + .stdin(fs::File::open("/dev/tty").unwrap()) + .status()?; + + Ok(()) +} + +fn ask_continue_editing(error: &[String]) -> bool { + println!("Calendar contains errors:\n{}", error.join("\n")); + println!("Continue editing? y/n:"); + + match fileutil::read_single_char_from_stdin().unwrap() { + 'y' => true, + _ => false + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use testutils::prepare_testdir; + use icalwrap::IcalComponent; + + #[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(); + + let dtstamp_prop = ical::icalproperty_kind_ICAL_DTSTAMP_PROPERTY; + assert_eq!("20130101T010203Z", event.get_property(dtstamp_prop).unwrap().get_value()); + + let last_modified_kind = ical::icalproperty_kind_ICAL_LASTMODIFIED_PROPERTY; + assert_eq!("20130101T010203Z", event.get_property(last_modified_kind).unwrap().get_value()); + } +} |