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
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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);
	}
}