diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2016-08-09 12:28:20 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2016-08-09 15:47:55 +0200 |
commit | e250ca632e2253958672691c80708ab7f63f5c9c (patch) | |
tree | 03b058431ce6b6b68d7df26fbb0722ec40d8da6e /libimagentryedit | |
parent | 4a317b253c6938b3ad86eae826b523888bfe9298 (diff) |
Move edit code from libimagrt
Diffstat (limited to 'libimagentryedit')
-rw-r--r-- | libimagentryedit/src/edit.rs | 80 | ||||
-rw-r--r-- | libimagentryedit/src/lib.rs | 7 |
2 files changed, 81 insertions, 6 deletions
diff --git a/libimagentryedit/src/edit.rs b/libimagentryedit/src/edit.rs new file mode 100644 index 00000000..b04bec06 --- /dev/null +++ b/libimagentryedit/src/edit.rs @@ -0,0 +1,80 @@ +use std::ops::DerefMut; + +use runtime::Runtime; +use error::RuntimeError; +use error::RuntimeErrorKind; + +use libimagstore::store::FileLockEntry; +use libimagstore::store::Entry; + +use libimagerror::into::IntoError; + +pub type EditResult<T> = Result<T, RuntimeError>; + +pub trait Edit { + fn edit_content(&mut self, rt: &Runtime) -> EditResult<()>; +} + +impl Edit for String { + + fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> { + edit_in_tmpfile(rt, self).map(|_| ()) + } + +} + +impl Edit for Entry { + + fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> { + edit_in_tmpfile(rt, self.get_content_mut()) + .map(|_| ()) + } + +} + +impl<'a> Edit for FileLockEntry<'a> { + + fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> { + self.deref_mut().edit_content(rt) + } + +} + +pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> EditResult<()> { + use tempfile::NamedTempFile; + use std::io::Seek; + use std::io::Read; + use std::io::SeekFrom; + use std::io::Write; + + let file = try!(NamedTempFile::new()); + let file_path = file.path(); + let mut file = try!(file.reopen()); + + try!(file.write_all(&s.clone().into_bytes()[..])); + try!(file.sync_data()); + + if let Some(mut editor) = rt.editor() { + let exit_status = editor.arg(file_path).status(); + + match exit_status.map(|s| s.success()).map_err(Box::new) { + Ok(true) => { + file.sync_data() + .and_then(|_| file.seek(SeekFrom::Start(0))) + .and_then(|_| { + let mut new_s = String::new(); + let res = file.read_to_string(&mut new_s); + *s = new_s; + res + }) + .map(|_| ()) + .map_err(Box::new) + .map_err(|e| RuntimeErrorKind::IOError.into_error_with_cause(e)) + }, + Ok(false) => Err(RuntimeErrorKind::ProcessExitFailure.into()), + Err(e) => Err(RuntimeErrorKind::IOError.into_error_with_cause(e)), + } + } else { + Err(RuntimeErrorKind::Instantiate.into()) + } +} diff --git a/libimagentryedit/src/lib.rs b/libimagentryedit/src/lib.rs index cdfbe1aa..99946a87 100644 --- a/libimagentryedit/src/lib.rs +++ b/libimagentryedit/src/lib.rs @@ -1,6 +1 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - } -} +pub mod edit; |