Macro konst::const_eq_for[][src]

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) *) ?) => { ... };
}
This is supported on crate feature cmp only.
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 comparing Option<T>. example

  • range: for comparing Range<T>. example

  • range_inclusive: for comparing RangeInclusive<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:

  • (passing nothing): Compares the item using the const_eq macro. example

  • , |item| <expression>: Converts the item with <expression> to a type that can be compared using the const_eq macro. example

  • , |left_item, right_item| <expression>: Compares the items with <expression>, which must evaluate to a bool. example

  • , path::to::function: Compares the items using the passed function, which must evaluate to a bool. 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 CMP_HERE: bool = const_eq_for!(slice; HERE, HERE);
assert!( CMP_HERE );

const CMP_HERE_THERE: bool = const_eq_for!(slice; HERE, THERE);
assert!( !CMP_HERE_THERE );

const CMP_THERE_THERE: bool = const_eq_for!(slice; THERE, THERE);
assert!( CMP_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 CMP_CHEAT: bool = eq_slice_direction(CHEAT_CODE, CHEAT_CODE);
assert!( CMP_CHEAT );

const CMP_CHEAT_CLOCK: bool = eq_slice_direction(CHEAT_CODE, CLOCKWISE);
assert!( !CMP_CHEAT_CLOCK );

const CMP_CLOCK_CLOCK: bool = eq_slice_direction(CLOCKWISE, CLOCKWISE);
assert!( CMP_CLOCK_CLOCK );

Comparing Options

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 SOME_SOME: bool = eq_opt_tuple(&SOME, &SOME);
assert!( SOME_SOME );

const SOME_NONE: bool = eq_opt_tuple(&SOME, &NONE);
assert!( !SOME_NONE );

const NONE_NONE: bool = eq_opt_tuple(&NONE, &NONE);
assert!( NONE_NONE );

Comparing Ranges

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 FOO_FOO: bool = const_eq_for!(range; FOO, FOO);
assert!( FOO_FOO );

const FOO_BAR: bool = const_eq_for!(range; FOO, BAR);
assert!( !FOO_BAR );

const BAR_BAR: bool = const_eq_for!(range; BAR, BAR);
assert!( BAR_BAR );

Comparing RangeInclusives

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 FOO_FOO: bool = const_eq_for!(range_inclusive; FOO, FOO);
assert!( FOO_FOO );

const FOO_BAR: bool = const_eq_for!(range_inclusive; FOO, BAR, WeekDay::const_eq);
assert!( !FOO_BAR );

const BAR_BAR: bool = const_eq_for!(range_inclusive; BAR, BAR, WeekDay::const_eq);
assert!( BAR_BAR );