Merge pull request #1103 from matthiasbeyer/libimagentrygps/more-functionality

libimagentrygps: More functionality
This commit is contained in:
Matthias Beyer 2017-09-21 19:01:12 +02:00 committed by GitHub
commit 3884e4232c
2 changed files with 62 additions and 0 deletions

View file

@ -26,12 +26,32 @@ use libimagstore::store::Entry;
use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadExt;
use toml_query::insert::TomlValueInsertExt; use toml_query::insert::TomlValueInsertExt;
use toml_query::delete::TomlValueDeleteExt;
pub trait GPSEntry { pub trait GPSEntry {
fn set_coordinates(&mut self, c: Coordinates) -> Result<()>; fn set_coordinates(&mut self, c: Coordinates) -> Result<()>;
fn get_coordinates(&self) -> Result<Option<Coordinates>>; fn get_coordinates(&self) -> Result<Option<Coordinates>>;
/// Remove the coordinates from the entry
///
/// # Returns
///
/// The return type is a bit complicated, but that has a reason:
///
/// The outer Result<_> is used for notifying a failure during the header read/write action.
/// If the Option<_> is Some(_), the value was deleted.
/// The inner Result<_> is used for parsing failures during the parsing of the deleted value.
///
/// So:
///
/// * Ok(Some(Ok(_))) if the coordinates were deleted, returning the deleted value
/// * Ok(Some(Err(_))) if the coordinates were deleted, but the deleted value couldn't be parsed
/// * Ok(None) if there were no coordinates to delete
/// * Err(e) if the deleting failed
///
fn remove_coordinates(&mut self) -> Result<Option<Result<Coordinates>>>;
} }
impl GPSEntry for Entry { impl GPSEntry for Entry {
@ -51,6 +71,12 @@ impl GPSEntry for Entry {
} }
} }
fn remove_coordinates(&mut self) -> Result<Option<Result<Coordinates>>> {
self.get_header_mut()
.delete("gps.coordinates")
.chain_err(|| GPSEK::HeaderWriteError)
.map(|opt| opt.as_ref().map(Coordinates::from_value))
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -18,6 +18,9 @@
// //
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
use toml::Value; use toml::Value;
@ -46,6 +49,19 @@ impl GPSValue {
seconds: s seconds: s
} }
} }
pub fn degree(&self) -> i8 {
self.degree
}
pub fn minutes(&self) -> i8 {
self.minutes
}
pub fn seconds(&self) -> i8 {
self.seconds
}
} }
@ -96,6 +112,12 @@ impl FromValue for GPSValue {
} }
impl Display for GPSValue {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}° {}\" {}'", self.degree, self.minutes, self.seconds)
}
}
/// Data-transfer type for transfering longitude-latitude-pairs /// Data-transfer type for transfering longitude-latitude-pairs
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Coordinates { pub struct Coordinates {
@ -110,6 +132,14 @@ impl Coordinates {
latitude: lat, latitude: lat,
} }
} }
pub fn longitude(&self) -> &GPSValue {
&self.longitude
}
pub fn latitude(&self) -> &GPSValue {
&self.latitude
}
} }
impl Into<Value> for Coordinates { impl Into<Value> for Coordinates {
@ -145,6 +175,12 @@ impl FromValue for Coordinates {
} }
impl Display for Coordinates {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "longitude = {}\nlatitude = {}", self.longitude, self.latitude)
}
}
/// Helper to convert a i64 to i8 or return an error if this doesn't work. /// Helper to convert a i64 to i8 or return an error if this doesn't work.
fn i64_to_i8(i: i64) -> Result<i8> { fn i64_to_i8(i: i64) -> Result<i8> {
if i > (<i8>::max_value() as i64) { if i > (<i8>::max_value() as i64) {