enum-flags 0.3.0-preview2

EnumFlags is a csharp like enum flags implementation.
Documentation
#![feature(arbitrary_enum_discriminant)]

use enum_flags::enum_flags;


#[test]
fn test_bitor(){

    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum State {
        None= 0,
        A = 1,
        B = 2,
        C = 4
    }

    let s: State = State::A | State::B;

    assert_eq!("(State::A | State::B)", format!("{:?}", s).as_str())
}

#[test]
fn test_bitor_assign(){

    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum State {
        None= 0,
        A = 1,
        B = 2,
        C = 4
    }

    let mut s: State = State::A;

    s |= State::B;

    assert_eq!("(State::A | State::B)", format!("{:?}", s).as_str())
}

#[test]
fn test_has_flag(){

    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum State {
        None= 0,
        A = 1,
        B = 2,
        C = 4
    }

    let s: State = State::A | State::B;

    assert!(s.has_flag(State::B));
    assert!(s.has_b());
    assert!(!s.has_flag(State::C));
    assert!(!s.has_flag(State::None));
}

#[test]
fn test_has_flag2(){


    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum State {
        None= 0,
        A = 1,
        B = 2,
        C = 4
    }

    let s: State = State::None;
    assert!(s.has_flag(State::None));
    assert!(s.has_none());
}

#[test]
fn test_bitand(){

    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum State {
        None= 0,
        A = 1,
        B = 2,
        C = 4
    }

    let s: State = State::A | State::B;
    let s = s & State::C;
    assert_eq!(State::None, s);
}

#[test]
fn test_bitand_assign(){

    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum State {
        None= 0,
        A = 1,
        B = 2,
        C = 4
    }

    let mut s: State = State::A | State::B;
    s &= State::C;
    assert_eq!(State::None, s);
}

#[test]
fn test_union(){
    #[repr(u8)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }

    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!(e1 | e2, Flags::A | Flags::B | Flags::C) // union
}

#[test]
fn test_intersection(){
    #[repr(u8)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }

    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!(e1 & e2, Flags::C) // intersection
}

#[test]
fn test_xor(){
    #[repr(u8)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }

    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!(e1 ^ e2, Flags::A | Flags::B);
}


#[test]
fn test_deletion(){
    #[repr(u8)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }


    let e1 = Flags::A | Flags::C;
    assert_eq!(e1 & (!Flags::C), Flags::A.as_num());
    assert_eq!(e1 - Flags::C , Flags::A);
}


#[test]
fn test_empty(){
    #[repr(u32)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }

    let e1 = Flags::None;
    assert!(e1.is_empty());
    assert!(!Flags::A.is_empty());
    assert!(!(Flags::A | Flags::B).is_empty());
}


#[test]
fn test_is_all(){
    #[repr(u32)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }

    let e1 = Flags::None;
    assert!(!e1.is_all());

    let e1 = Flags::A;
    assert!(!e1.is_all());

    let e1 = Flags::A | Flags::C;
    assert!(!e1.is_all());

    let e1 = Flags::A | Flags::C | Flags::B;
    assert!(e1.is_all());

    let e1 = Flags::A | Flags::C | Flags::B | Flags::None;
    assert!(e1.is_all());
}

#[test]
fn test_contains(){
    #[repr(u32)]
    #[enum_flags]
    #[derive(Copy, Clone, PartialEq)]
    enum Flags{
        None = 0,
        A = 1,
        B = 2,
        C = 4
    }

    let e1 = Flags::A;
    assert!(e1.contains(Flags::A));

    let e1 = Flags::A | Flags::C;
    assert!(e1.contains(Flags::A));

    let e1 = Flags::A | Flags::C;
    assert!(!e1.contains(Flags::None));



    let e1 = Flags::None;
    assert!(e1.contains(Flags::None));
}