ptth/crates/always_equal/src/lib.rs

147 lines
2.6 KiB
Rust

pub mod test {
#[derive (Debug)]
pub struct AlwaysEqual <T> {
inner: Option <T>,
}
impl <T> AlwaysEqual <T> {
pub fn into_inner (self) -> T {
match self.inner {
Some (x) => x,
None => unreachable! (),
}
}
pub fn testing_blank () -> Self {
Self {
inner: None,
}
}
}
impl <T: Default> Default for AlwaysEqual <T> {
fn default () -> Self {
Self::from (T::default ())
}
}
impl <T> From <T> for AlwaysEqual <T> {
fn from (inner: T) -> Self {
Self {
inner: Some (inner),
}
}
}
impl <T> PartialEq for AlwaysEqual <T> {
fn eq (&self, other: &Self) -> bool {
self.inner.is_none () || other.inner.is_none ()
}
}
}
pub mod prod {
use std::fmt;
pub struct AlwaysEqual <T> {
inner: T,
}
impl <T: fmt::Debug> fmt::Debug for AlwaysEqual <T> {
fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt (f)
}
}
impl <T: fmt::Display> fmt::Display for AlwaysEqual <T> {
fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt (f)
}
}
impl <T> AlwaysEqual <T> {
pub fn into_inner (self) -> T {
self.inner
}
}
impl <T> From <T> for AlwaysEqual <T> {
fn from (inner: T) -> Self {
Self {
inner,
}
}
}
impl <T> PartialEq for AlwaysEqual <T> {
fn eq (&self, _other: &Self) -> bool {
false
}
}
}
#[cfg (test)]
mod tests {
use std::fs::File;
use super::test::*;
// Can't impl Clone or PartialEq because of the File
type CantCompare = Option <File>;
#[derive (Debug, Default, PartialEq)]
struct MyStruct
{
file: AlwaysEqual <CantCompare>,
name: &'static str,
}
#[test]
fn test_1 () {
let concrete_1 = MyStruct {
file: None.into (),
name: "my_struct",
};
let concrete_2 = MyStruct {
file: None.into (),
name: "my_struct",
};
let concrete_bad = MyStruct {
file: None.into (),
name: "not_my_struct",
};
assert_ne! (concrete_1, concrete_2);
assert_ne! (concrete_2, concrete_bad);
assert_ne! (concrete_bad, concrete_1);
let dummy_1 = MyStruct {
file: AlwaysEqual::testing_blank (),
name: "my_struct",
};
let dummy_2 = MyStruct {
file: AlwaysEqual::testing_blank (),
name: "my_struct",
};
let dummy_bad = MyStruct {
file: AlwaysEqual::testing_blank (),
name: "not_my_struct",
};
assert_eq! (dummy_1, dummy_2);
assert_ne! (dummy_2, dummy_bad);
assert_ne! (dummy_bad, dummy_1);
assert_eq! (concrete_1, dummy_1);
assert_eq! (concrete_bad, dummy_bad);
}
#[test]
fn test_2 () {
let v1 = Vec::<AlwaysEqual <File>>::new ();
let v2 = Vec::<AlwaysEqual <File>>::new ();
assert_eq! (v1, v2);
}
}