Implement From<(u32, u32)> for Rational and i32 version for SRational.

This commit is contained in:
KAMADA Ken'ichi 2019-04-12 23:35:28 +09:00
parent 437b1a1750
commit e1e4800eea
4 changed files with 45 additions and 45 deletions

View File

@ -1516,11 +1516,11 @@ mod tests {
assert_eq!(buf, "0, 1, 2"); assert_eq!(buf, "0, 1, 2");
let mut buf = String::new(); let mut buf = String::new();
d_sub_comma(&mut buf, &[Rational { num: 3, denom: 5 }]).unwrap(); d_sub_comma(&mut buf, &[Rational::from((3, 5))]).unwrap();
assert_eq!(buf, "3/5"); assert_eq!(buf, "3/5");
let mut buf = String::new(); let mut buf = String::new();
d_sub_comma_f64(&mut buf, &[Rational { num: 1, denom: 2 }]).unwrap(); d_sub_comma_f64(&mut buf, &[Rational::from((1, 2))]).unwrap();
assert_eq!(buf, "0.5"); assert_eq!(buf, "0.5");
let mut buf = String::new(); let mut buf = String::new();

View File

@ -278,12 +278,12 @@ impl<'a> Field<'a> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use exif::{Field, Rational, Tag, Value}; /// use exif::{Field, Tag, Value};
/// ///
/// let xres = Field { /// let xres = Field {
/// tag: Tag::XResolution, /// tag: Tag::XResolution,
/// thumbnail: false, /// thumbnail: false,
/// value: Value::Rational(vec![Rational { num: 72, denom: 1 }]), /// value: Value::Rational(vec![(72, 1).into()]),
/// }; /// };
/// let cm = Field { /// let cm = Field {
/// tag: Tag::ResolutionUnit, /// tag: Tag::ResolutionUnit,
@ -401,7 +401,6 @@ impl<'a> ProvideUnit<'a> for &'a Field<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::value::Rational;
// Before the error is returned, the IFD is parsed twice as the // Before the error is returned, the IFD is parsed twice as the
// 0th and 1st IFDs. // 0th and 1st IFDs.
@ -502,7 +501,7 @@ mod tests {
let xres = Field { let xres = Field {
tag: Tag::XResolution, tag: Tag::XResolution,
thumbnail: false, thumbnail: false,
value: Value::Rational(vec![Rational { num: 300, denom: 1 }]), value: Value::Rational(vec![(300, 1).into()]),
}; };
assert_eq!(xres.display_value().to_string(), assert_eq!(xres.display_value().to_string(),
"300"); "300");
@ -517,10 +516,7 @@ mod tests {
tag: Tag::GPSLatitude, tag: Tag::GPSLatitude,
thumbnail: false, thumbnail: false,
value: Value::Rational(vec![ value: Value::Rational(vec![
Rational { num: 10, denom: 1 }, (10, 1).into(), (0, 1).into(), (1, 10).into()]),
Rational { num: 0, denom: 1 },
Rational { num: 1, denom: 10 },
]),
}; };
assert_eq!(gpslat.display_value().to_string(), assert_eq!(gpslat.display_value().to_string(),
"10 deg 0 min 0.1 sec"); "10 deg 0 min 0.1 sec");

View File

@ -181,7 +181,7 @@ impl<'a> From<&'a DefaultValue> for Option<Value<'a>> {
DefaultValue::Ascii(s) => Some(Value::Ascii(s.to_vec())), DefaultValue::Ascii(s) => Some(Value::Ascii(s.to_vec())),
DefaultValue::Short(s) => Some(Value::Short(s.to_vec())), DefaultValue::Short(s) => Some(Value::Short(s.to_vec())),
DefaultValue::Rational(s) => Some(Value::Rational( DefaultValue::Rational(s) => Some(Value::Rational(
s.iter().map(|&t| tuple2rational(t)).collect())), s.iter().map(|&x| x.into()).collect())),
DefaultValue::Undefined(s) => Some(Value::Undefined(s, 0)), DefaultValue::Undefined(s) => Some(Value::Undefined(s, 0)),
DefaultValue::ContextDependent => None, DefaultValue::ContextDependent => None,
DefaultValue::Unspecified => None, DefaultValue::Unspecified => None,
@ -201,8 +201,10 @@ impl Rational {
} }
} }
fn tuple2rational(t: (u32, u32)) -> Rational { impl From<(u32, u32)> for Rational {
Rational { num: t.0, denom: t.1 } fn from(t: (u32, u32)) -> Rational {
Rational { num: t.0, denom: t.1 }
}
} }
impl fmt::Debug for Rational { impl fmt::Debug for Rational {
@ -241,6 +243,12 @@ impl SRational {
} }
} }
impl From<(i32, i32)> for SRational {
fn from(t: (i32, i32)) -> SRational {
SRational { num: t.0, denom: t.1 }
}
}
impl fmt::Debug for SRational { impl fmt::Debug for SRational {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "SRational({}/{})", self.num, self.denom) write!(f, "SRational({}/{})", self.num, self.denom)
@ -507,8 +515,9 @@ mod tests {
(b"x", vec![]), (b"x", vec![]),
(b"x\xa1\x02\x03\x04\x05\x06\x07\x08\ (b"x\xa1\x02\x03\x04\x05\x06\x07\x08\
\x09\x0a\x0b\x0c\xbd\x0e\x0f\x10", \x09\x0a\x0b\x0c\xbd\x0e\x0f\x10",
vec![Rational { num: 0xa1020304, denom: 0x05060708 }, vec![(0xa1020304, 0x05060708).into(),
Rational { num: 0x090a0b0c, denom: 0xbd0e0f10 }]), (0x090a0b0c, 0xbd0e0f10).into()]),
]; ];
let (unitlen, parser) = get_type_info::<BigEndian>(5); let (unitlen, parser) = get_type_info::<BigEndian>(5);
for &(data, ref ans) in sets { for &(data, ref ans) in sets {
@ -599,8 +608,8 @@ mod tests {
(b"x", vec![]), (b"x", vec![]),
(b"x\xa1\x02\x03\x04\x05\x06\x07\x08\ (b"x\xa1\x02\x03\x04\x05\x06\x07\x08\
\x09\x0a\x0b\x0c\xbd\x0e\x0f\x10", \x09\x0a\x0b\x0c\xbd\x0e\x0f\x10",
vec![SRational { num: -0x5efdfcfc, denom: 0x05060708 }, vec![(-0x5efdfcfc, 0x05060708).into(),
SRational { num: 0x090a0b0c, denom: -0x42f1f0f0 }]), (0x090a0b0c, -0x42f1f0f0).into()]),
]; ];
let (unitlen, parser) = get_type_info::<BigEndian>(10); let (unitlen, parser) = get_type_info::<BigEndian>(10);
for &(data, ref ans) in sets { for &(data, ref ans) in sets {
@ -716,10 +725,10 @@ mod tests {
#[test] #[test]
fn rational_fmt_display() { fn rational_fmt_display() {
let r = Rational { num: u32::max_value(), denom: u32::max_value() }; let r = Rational::from((u32::max_value(), u32::max_value()));
assert_eq!(format!("{}", r), "4294967295/4294967295"); assert_eq!(format!("{}", r), "4294967295/4294967295");
let r = Rational { num: 10, denom: 20 }; let r = Rational::from((10, 20));
assert_eq!(format!("{}", r), "10/20"); assert_eq!(format!("{}", r), "10/20");
assert_eq!(format!("{:11}", r), " 10/20"); assert_eq!(format!("{:11}", r), " 10/20");
assert_eq!(format!("{:3}", r), "10/20"); assert_eq!(format!("{:3}", r), "10/20");
@ -727,22 +736,22 @@ mod tests {
#[test] #[test]
fn srational_fmt_display() { fn srational_fmt_display() {
let r = SRational { num: i32::min_value(), denom: i32::min_value() }; let r = SRational::from((i32::min_value(), i32::min_value()));
assert_eq!(format!("{}", r), "-2147483648/-2147483648"); assert_eq!(format!("{}", r), "-2147483648/-2147483648");
let r = SRational { num: i32::max_value(), denom: i32::max_value() }; let r = SRational::from((i32::max_value(), i32::max_value()));
assert_eq!(format!("{}", r), "2147483647/2147483647"); assert_eq!(format!("{}", r), "2147483647/2147483647");
let r = SRational { num: -10, denom: 20 }; let r = SRational::from((-10, 20));
assert_eq!(format!("{}", r), "-10/20"); assert_eq!(format!("{}", r), "-10/20");
assert_eq!(format!("{:11}", r), " -10/20"); assert_eq!(format!("{:11}", r), " -10/20");
assert_eq!(format!("{:3}", r), "-10/20"); assert_eq!(format!("{:3}", r), "-10/20");
let r = SRational { num: 10, denom: -20 }; let r = SRational::from((10, -20));
assert_eq!(format!("{}", r), "10/-20"); assert_eq!(format!("{}", r), "10/-20");
assert_eq!(format!("{:11}", r), " 10/-20"); assert_eq!(format!("{:11}", r), " 10/-20");
assert_eq!(format!("{:3}", r), "10/-20"); assert_eq!(format!("{:3}", r), "10/-20");
let r = SRational { num: -10, denom: -20 }; let r = SRational::from((-10, -20));
assert_eq!(format!("{}", r), "-10/-20"); assert_eq!(format!("{}", r), "-10/-20");
assert_eq!(format!("{:11}", r), " -10/-20"); assert_eq!(format!("{:11}", r), " -10/-20");
assert_eq!(format!("{:3}", r), "-10/-20"); assert_eq!(format!("{:3}", r), "-10/-20");
@ -751,32 +760,30 @@ mod tests {
#[test] #[test]
fn ratioanl_f64() { fn ratioanl_f64() {
use std::{f64, u32}; use std::{f64, u32};
assert_eq!(f64::from(Rational { num: 1, denom: 2 }), 0.5); assert_eq!(f64::from(Rational::from((1, 2))), 0.5);
assert_eq!(f64::from(Rational { num: 1, denom: u32::MAX }), assert_eq!(f64::from(Rational::from((1, u32::MAX))),
2.3283064370807974e-10); 2.3283064370807974e-10);
assert_eq!(f64::from(Rational { num: u32::MAX, denom: 1 }), assert_eq!(f64::from(Rational::from((u32::MAX, 1))),
u32::MAX as f64); u32::MAX as f64);
assert_eq!(f64::from(Rational { num: u32::MAX - 1, denom: u32::MAX }), assert_eq!(f64::from(Rational::from((u32::MAX - 1, u32::MAX))),
0.9999999997671694); 0.9999999997671694);
assert_eq!(f64::from(Rational { num: u32::MAX, denom: u32::MAX - 1 }), assert_eq!(f64::from(Rational::from((u32::MAX, u32::MAX - 1))),
1.0000000002328306); 1.0000000002328306);
assert_eq!(f64::from(Rational { num: 1, denom: 0 }), f64::INFINITY); assert_eq!(f64::from(Rational::from((1, 0))), f64::INFINITY);
assert!(f64::from(Rational { num: 0, denom: 0 }).is_nan()); assert!(f64::from(Rational::from((0, 0))).is_nan());
assert_eq!(f64::from(SRational { num: 1, denom: 2 }), 0.5); assert_eq!(f64::from(SRational::from((1, 2))), 0.5);
assert_eq!(f64::from(SRational { num: -1, denom: 2 }), -0.5); assert_eq!(f64::from(SRational::from((-1, 2))), -0.5);
assert_eq!(f64::from(SRational { num: 1, denom: -2 }), -0.5); assert_eq!(f64::from(SRational::from((1, -2))), -0.5);
assert_eq!(f64::from(SRational { num: -1, denom: -2 }), 0.5); assert_eq!(f64::from(SRational::from((-1, -2))), 0.5);
assert_eq!(f64::from(SRational { num: 1, denom: 0 }), f64::INFINITY); assert_eq!(f64::from(SRational::from((1, 0))), f64::INFINITY);
assert_eq!(f64::from(SRational { num: -1, denom: 0 }), assert_eq!(f64::from(SRational::from((-1, 0))), f64::NEG_INFINITY);
f64::NEG_INFINITY);
} }
#[test] #[test]
fn rational_f32() { fn rational_f32() {
// If num and demon are converted to f32 before the division, // If num and demon are converted to f32 before the division,
// the precision is lost in this example. // the precision is lost in this example.
assert_eq!(f32::from(Rational { num: 1, denom: 16777217 }), assert_eq!(f32::from(Rational::from((1, 16777217))), 5.960464e-8);
5.960464e-8);
} }
} }

View File

@ -609,7 +609,6 @@ fn get_offset<W>(w: &mut W)
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::io::Cursor; use std::io::Cursor;
use crate::value::{Rational, SRational};
use super::*; use super::*;
#[test] #[test]
@ -787,8 +786,7 @@ mod tests {
(Value::Long(vec![0x01020304, 0x05060708]), (Value::Long(vec![0x01020304, 0x05060708]),
(4, 2, b"\x01\x02\x03\x04\x05\x06\x07\x08".to_vec()), (4, 2, b"\x01\x02\x03\x04\x05\x06\x07\x08".to_vec()),
(4, 2, b"\x04\x03\x02\x01\x08\x07\x06\x05".to_vec())), (4, 2, b"\x04\x03\x02\x01\x08\x07\x06\x05".to_vec())),
(Value::Rational(vec![Rational { num: 1, denom: 2}, (Value::Rational(vec![(1, 2).into(), (3, 4).into()]),
Rational { num: 3, denom: 4}]),
(5, 2, b"\0\0\0\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04".to_vec()), (5, 2, b"\0\0\0\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04".to_vec()),
(5, 2, b"\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04\0\0\0".to_vec())), (5, 2, b"\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04\0\0\0".to_vec())),
(Value::SByte(vec![-2, -128]), (Value::SByte(vec![-2, -128]),
@ -803,8 +801,7 @@ mod tests {
(Value::SLong(vec![-2, -0x80000000]), (Value::SLong(vec![-2, -0x80000000]),
(9, 2, b"\xff\xff\xff\xfe\x80\x00\x00\x00".to_vec()), (9, 2, b"\xff\xff\xff\xfe\x80\x00\x00\x00".to_vec()),
(9, 2, b"\xfe\xff\xff\xff\x00\x00\x00\x80".to_vec())), (9, 2, b"\xfe\xff\xff\xff\x00\x00\x00\x80".to_vec())),
(Value::SRational(vec![SRational { num: -1, denom: -2}, (Value::SRational(vec![(-1, -2).into(), (-3, -4).into()]),
SRational { num: -3, denom: -4}]),
(10, 2, b"\xff\xff\xff\xff\xff\xff\xff\xfe\ (10, 2, b"\xff\xff\xff\xff\xff\xff\xff\xfe\
\xff\xff\xff\xfd\xff\xff\xff\xfc".to_vec()), \xff\xff\xff\xfd\xff\xff\xff\xfc".to_vec()),
(10, 2, b"\xff\xff\xff\xff\xfe\xff\xff\xff\ (10, 2, b"\xff\xff\xff\xff\xfe\xff\xff\xff\