macro_rules! const_eq_for {
(
slice;
$left_slice:expr,
$right_slice:expr
$(, $($comparison:tt)* )?
) => { ... };
(
option;
$left_opt:expr,
$right_opt:expr
$(, $($comparison:tt)* )?
) => { ... };
(
range;
$left_range:expr,
$right_range:expr
$(, $($comparison:tt)* )?
) => { ... };
(
range_inclusive;
$left_range:expr,
$right_range:expr
$(, $($comparison:tt)* )?
) => { ... };
}
Expand description
Compares two standard library types for equality,
that can’t be compared with const_eq
.
§Types
This macro supports multiple types with different prefixes:
-
slice
: for comparing&[T]
. example -
option
: for comparingOption<T>
. example -
range
: for comparingRange<T>
. example -
range_inclusive
: for comparingRangeInclusive<T>
. example
§Limitations
The arguments must be concrete types, and have a fully inferred type. eg: if you pass an integer literal it must have a suffix to indicate its type.
§Arguments
The arguments take this form
const_eq_for!(type; left_value, right_value <comparator> )
§Comparator argument
The <comparator>
argument can be any of:
-
const_eq
macro. example -
, |item| <expression>
: Converts the item with<expression>
to a type that can be compared using theconst_eq
macro. example -
, |left_item, right_item| <expression>
: Compares the items with<expression>
, which must evaluate to abool
. example -
, path::to::function
: Compares the items using the passed function, which must evaluate to abool
. example
§Examples
§Comparing slices of structs
use konst::{const_eq_for, eq_str};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Location {
pub file: &'static str,
pub column: u32,
pub line: u32,
}
konst::impl_cmp! {
impl Location;
pub const fn const_eq(&self, other: &Self) -> bool {
eq_str(self.file, other.file) &&
self.column == other.column &&
self.line == other.line
}
}
const HERE: &[Location] = &[here!(), here!(), here!(), here!()];
const THERE: &[Location] = &[here!(), here!(), here!(), here!()];
const _: () = {
assert!( const_eq_for!(slice; HERE, HERE));
assert!(!const_eq_for!(slice; HERE, THERE));
assert!( const_eq_for!(slice; THERE, THERE));
};
§Comparing slices of field-less enums
#[derive(Copy, Clone)]
enum Direction {
Left,
Right,
Up,
Down,
}
use Direction::*;
const fn eq_slice_direction(left: &[Direction], right: &[Direction]) -> bool {
konst::const_eq_for!(slice; left, right, |&x| x as u8)
}
const CHEAT_CODE: &[Direction] = &[Up, Up, Down, Down, Left, Right, Left, Right];
const CLOCKWISE: &[Direction] = &[Up, Right, Down, Left];
const _: () = {
assert!( eq_slice_direction(CHEAT_CODE, CHEAT_CODE));
assert!(!eq_slice_direction(CHEAT_CODE, CLOCKWISE));
assert!( eq_slice_direction(CLOCKWISE, CLOCKWISE));
};
§Comparing Option
s
use konst::const_eq_for;
const SOME: Option<(u32, u32)> = Some((3, 5));
const NONE: Option<(u32, u32)> = None;
const fn eq_opt_tuple(left: &Option<(u32, u32)>, right: &Option<(u32, u32)>) -> bool {
const_eq_for!(option; left, right, |l, r| l.0 == r.0 && l.1 == r.1 )
}
const _: () = {
assert!( eq_opt_tuple(&SOME, &SOME));
assert!(!eq_opt_tuple(&SOME, &NONE));
assert!( eq_opt_tuple(&NONE, &NONE));
};
§Comparing Range
s
use konst::{const_eq_for, impl_cmp};
use std::ops::Range;
#[derive(Copy, Clone)]
pub enum Month {
January,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November,
December,
}
use Month::*;
konst::impl_cmp! {
impl Month;
pub const fn const_eq(&self, other: &Self) -> bool {
*self as u8 == *other as u8
}
}
const FOO: Range<Month> = January..April;
const BAR: Range<Month> = October..December;
const _: () = {
assert!( const_eq_for!(range; FOO, FOO));
assert!(!const_eq_for!(range; FOO, BAR));
assert!( const_eq_for!(range; BAR, BAR));
};
§Comparing RangeInclusive
s
use konst::{const_eq_for, impl_cmp};
use std::ops::RangeInclusive;
#[derive(Copy, Clone)]
pub enum WeekDay {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
use WeekDay::*;
konst::impl_cmp! {
impl WeekDay;
pub const fn const_eq(&self, other: &Self) -> bool {
*self as u8 == *other as u8
}
}
const FOO: RangeInclusive<WeekDay> = Monday..=Thursday;
const BAR: RangeInclusive<WeekDay> = Friday..=Sunday;
const _: () = {
assert!( const_eq_for!(range_inclusive; FOO, FOO));
assert!(!const_eq_for!(range_inclusive; FOO, BAR, WeekDay::const_eq));
assert!( const_eq_for!(range_inclusive; BAR, BAR, WeekDay::const_eq));
};