1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
//! Miscellanea module.
//!
//! Provides cross modules useful enums, functions, traits.
/// Default error tolerance used inside [`IsClose`] trait.
pub const EPSILON: f32 = 1e-4;
/// Trait for equivalence between two objects,
/// up to a certain error [`tolerance`](constant@EPSILON).
///
/// Primitive elements that compose those objects must
/// implement [`IsClose`] trait to derive this trait.
pub trait IsClose<Rhs = Self> {
fn is_close(&self, other: Self) -> bool;
}
impl IsClose for f32 {
/// Return `true` if absolute value between two `f32`
/// is less than [`EPSILON`]
fn is_close(&self, other: f32) -> bool {
(self - other).abs() < EPSILON
}
}
/// Variants of byte/bit endianness.
pub enum ByteOrder {
BigEndian,
LittleEndian,
}
/// 2D point struct used for shape's surface parametrization
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vector2D {
pub u: f32,
pub v: f32,
}
impl IsClose for Vector2D {
/// Return `true` if the three xyz components of two [`Vector2D`] are [close](trait@IsClose).
fn is_close(&self, other: Self) -> bool {
self.u.is_close(other.u) && self.v.is_close(other.v)
}
}
/// Macro for wrap exit logic inside [`main`](fn.main.html).
#[macro_export]
macro_rules! exit {
($a:expr) => {
match $a {
Ok(()) => exit(0),
Err(e) => {
eprintln!("{} {:#}", "[error]".red().bold(), e);
exit(1)
},
}
};
}
/// Macro for fail fast in [`main`](fn.main.html) subcommands
/// (e.g. inside [`convert`](fn.convert.html)).
///
/// When invalid or unsupported ldr file is provided via cli fail immediately.
///
/// Re-use of built-in logic inside
/// [`write_ldr_file`](hdrimage/struct.HdrImage.html#method.write_ldr_file).
#[macro_export]
macro_rules! check {
($a:expr) => {
match ImageFormat::from_path($a).map_err(HdrImageErr::LdrFileWriteFailure) {
Ok(ImageFormat::Png) => Ok(()),
Ok(ImageFormat::Farbfeld) => Ok(()),
Ok(_) => Err(HdrImageErr::UnsupportedLdrFileFormat(String::from(
$a.extension().unwrap().to_str().unwrap_or(""),
))),
Err(err) => Err(err),
}
};
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_is_close_float() {
assert!((EPSILON * 1e-1 + 1.0).is_close(1.0));
assert!(!(EPSILON + 1.0).is_close(1.0))
}
#[test]
fn test_is_close_vector2d() {
assert!(Vector2D {
u: EPSILON * 1e-1 + 1.0,
v: 1.0,
}
.is_close(Vector2D { u: 1.0, v: 1.0 }))
}
}