use attr_bounds::bounds; #[test] fn empty_bounds() { #[bounds()] struct Wrapper(T); let _ = Wrapper(42); } #[test] fn enum_bounds() { #[bounds(A: std::fmt::Display)] #[bounds(B: std::ops::Add)] #[derive(Debug)] enum Either { Left(A), Right(B), } let left = Either::<&str, i32>::Left("foo"); let right = Either::<&str, i32>::Right(42); assert_eq!(format!("{left:?}"), "Left(\"foo\")"); assert_eq!(format!("{right:?}"), "Right(42)"); } #[test] fn fn_bounds() { #[bounds(T: Clone)] fn clone(var: &T) -> T { var.clone() } let v1 = vec![1, 2, 3]; let v2 = clone(&v1); assert_eq!(v1, v2); } #[test] fn assoc_fn_bounds() { trait Display { #[bounds(T: std::fmt::Display)] fn display(var: T); } impl Display for () { #[bounds(T: std::fmt::Display)] fn display(var: T) { println!("{var}"); } } <()>::display(42); } #[test] fn impl_bounds() { use std::{fmt::Display, ops::Add}; trait Foo where T: Copy + Display + Add, { fn foo(self, x: T) -> String; } #[bounds(S: Display)] #[bounds(T: Copy + Display + Add)] impl Foo for S { fn foo(self, x: T) -> String { self.to_string() + &(x + x).to_string() } } assert_eq!(42i32.foo(42i64), "4284"); } #[test] fn struct_bounds() { #[bounds(T: std::ops::Add)] #[derive(Debug)] struct Wrapper(T); let var = Wrapper(42); assert_eq!(format!("{var:?}"), "Wrapper(42)"); } #[test] fn trait_bounds() { #[bounds(Self: Clone + std::ops::Mul)] trait Square { fn square(&self) -> Self; } impl Square for i32 { fn square(&self) -> Self { self * self } } assert_eq!(42i32.square(), 42 * 42); } #[test] fn type_bounds() { trait LendingIterator { #[bounds(Self: 'a)] type Item<'a>; fn next(&mut self) -> Option>; } struct WindowsMut<'t, T> { slice: &'t mut [T], cursor: usize, window_size: usize, } impl<'t, T> LendingIterator for WindowsMut<'t, T> { #[bounds(Self: 'a)] type Item<'a> = &'a mut [T]; fn next(&mut self) -> Option> { let window = self .slice .get_mut(self.cursor..self.cursor + self.window_size)?; self.cursor += 1; Some(window) } } let mut v = vec![1, 2, 3, 4, 5]; let mut w = WindowsMut { slice: v.as_mut_slice(), cursor: 0, window_size: 3, }; while let Some(w) = w.next() { for a in w.iter_mut() { *a += 1; } } assert_eq!(v, &[2, 4, 6, 6, 6]); } #[test] fn union_bounds() { #[bounds(A: Copy)] #[bounds(B: Copy)] union Union { a: A, b: B, } let _ = Union:: { a: 42 }; let _ = Union:: { b: 255 }; }