147 lines
2.6 KiB
Rust
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);
|
||
|
}
|
||
|
}
|