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
147
148
149
150
151
152
153
154
use mio::EventSet;
use std::{fmt, ops};

/// A Tokio aware source.
///
/// For more details, read the module level documentation.
pub trait Readiness {
    /// Returns true if the value is currently readable.
    fn is_readable(&self) -> bool;

    /// Returns true if the value is currently writable.
    fn is_writable(&self) -> bool;
}

const READABLE: usize = 1;
const WRITABLE: usize = 1 << 2;

/// Represents the state of readiness.
///
/// A given source may be ready to complete zero, one, or more operations.
/// `Ready` represents which operations the source is ready to complete.
///
/// Currently, the operations are reading and writing.
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct Ready(usize);

impl Ready {
    /// No readiness
    pub fn none() -> Ready {
        Ready(0)
    }

    /// Read and write readiness
    pub fn all() -> Ready {
        Ready::readable() | Ready::writable()
    }

    /// Read readiness
    pub fn readable() -> Ready {
        Ready(READABLE)
    }

    /// Write readiness
    pub fn writable() -> Ready {
        Ready(WRITABLE)
    }

    /// Returns true when read readiness is included
    pub fn is_readable(&self) -> bool {
        self.contains(Ready::readable())
    }

    /// Returns true when write readiness is included
    pub fn is_writable(&self) -> bool {
        self.contains(Ready::writable())
    }

    /// Returns true when the specified readiness is included
    pub fn contains(&self, other: Ready) -> bool {
        (*self & other) == other
    }
}

impl From<EventSet> for Ready {
    fn from(src: EventSet) -> Ready {
        let mut ret = Ready::none();

        if src.is_readable() { ret = ret | Ready::readable() }
        if src.is_writable() { ret = ret | Ready::writable() }

        ret
    }
}

impl Into<EventSet> for Ready {
    fn into(self) -> EventSet {
        let mut ret = EventSet::none();

        if self.is_readable() { ret = ret | EventSet::readable() }
        if self.is_writable() { ret = ret | EventSet::writable() }

        ret
    }
}

impl ops::BitOr for Ready {
    type Output = Ready;

    #[inline]
    fn bitor(self, other: Ready) -> Ready {
        Ready(self.0 | other.0)
    }
}

impl ops::BitXor for Ready {
    type Output = Ready;

    #[inline]
    fn bitxor(self, other: Ready) -> Ready {
        Ready(self.0 ^ other.0)
    }
}

impl ops::BitAnd for Ready {
    type Output = Ready;

    #[inline]
    fn bitand(self, other: Ready) -> Ready {
        Ready(self.0 & other.0)
    }
}

impl ops::Sub for Ready {
    type Output = Ready;

    #[inline]
    fn sub(self, other: Ready) -> Ready {
        Ready(self.0 & !other.0)
    }
}

impl ops::Not for Ready {
    type Output = Ready;

    #[inline]
    fn not(self) -> Ready {
        Ready(!self.0 & Ready::all().0)
    }
}

impl fmt::Debug for Ready {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (Ready::readable(), "Readable"),
            (Ready::writable(), "Writable"),
            ];

        try!(write!(fmt, "Ready {{"));

        for &(flag, msg) in &flags {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        try!(write!(fmt, "}}"));

        Ok(())
    }
}