tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

kleene_value.rs (3577B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 //! Kleen logic: https://en.wikipedia.org/wiki/Three-valued_logic#Kleene_and_Priest_logics
      6 
      7 /// A "trilean" value based on Kleen logic.
      8 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
      9 pub enum KleeneValue {
     10    /// False
     11    False = 0,
     12    /// True
     13    True = 1,
     14    /// Either true or false, but we’re not sure which yet.
     15    Unknown,
     16 }
     17 
     18 impl From<bool> for KleeneValue {
     19    fn from(b: bool) -> Self {
     20        if b {
     21            Self::True
     22        } else {
     23            Self::False
     24        }
     25    }
     26 }
     27 
     28 impl KleeneValue {
     29    /// Turns this Kleene value to a bool, taking the unknown value as an
     30    /// argument.
     31    pub fn to_bool(self, unknown: bool) -> bool {
     32        match self {
     33            Self::True => true,
     34            Self::False => false,
     35            Self::Unknown => unknown,
     36        }
     37    }
     38 
     39    /// Return true if any result of f() is definitely true.
     40    /// Otherwise, return the `or` of all values.
     41    /// Returns false if empty, like that of `Iterator`.
     42    #[inline(always)]
     43    pub fn any<T>(iter: impl Iterator<Item = T>, f: impl FnMut(T) -> Self) -> Self {
     44        Self::any_value(iter, Self::True, Self::False, |a, b| a | b, f)
     45    }
     46 
     47    /// Return false if any results of f() is definitely false.
     48    /// Otherwise, return the `and` of all values.
     49    /// Returns true if empty, opposite of `Iterator`.
     50    #[inline(always)]
     51    pub fn any_false<T>(iter: impl Iterator<Item = T>, f: impl FnMut(T) -> Self) -> Self {
     52        Self::any_value(iter, Self::False, Self::True, |a, b| a & b, f)
     53    }
     54 
     55    #[inline(always)]
     56    fn any_value<T>(
     57        iter: impl Iterator<Item = T>,
     58        value: Self,
     59        on_empty: Self,
     60        op: impl Fn(Self, Self) -> Self,
     61        mut f: impl FnMut(T) -> Self,
     62    ) -> Self {
     63        let mut result = None;
     64        for item in iter {
     65            let r = f(item);
     66            if r == value {
     67                return r;
     68            }
     69            if let Some(v) = result.as_mut() {
     70                *v = op(*v, r);
     71            } else {
     72                result = Some(r);
     73            }
     74        }
     75        result.unwrap_or(on_empty)
     76    }
     77 }
     78 
     79 impl std::ops::Not for KleeneValue {
     80    type Output = Self;
     81 
     82    fn not(self) -> Self {
     83        match self {
     84            Self::True => Self::False,
     85            Self::False => Self::True,
     86            Self::Unknown => Self::Unknown,
     87        }
     88    }
     89 }
     90 
     91 // Implements the logical and operation.
     92 impl std::ops::BitAnd for KleeneValue {
     93    type Output = Self;
     94 
     95    fn bitand(self, other: Self) -> Self {
     96        if self == Self::False || other == Self::False {
     97            return Self::False;
     98        }
     99        if self == Self::Unknown || other == Self::Unknown {
    100            return Self::Unknown;
    101        }
    102        Self::True
    103    }
    104 }
    105 
    106 // Implements the logical or operation.
    107 impl std::ops::BitOr for KleeneValue {
    108    type Output = Self;
    109 
    110    fn bitor(self, other: Self) -> Self {
    111        if self == Self::True || other == Self::True {
    112            return Self::True;
    113        }
    114        if self == Self::Unknown || other == Self::Unknown {
    115            return Self::Unknown;
    116        }
    117        Self::False
    118    }
    119 }
    120 
    121 impl std::ops::BitOrAssign for KleeneValue {
    122    fn bitor_assign(&mut self, other: Self) {
    123        *self = *self | other;
    124    }
    125 }
    126 
    127 impl std::ops::BitAndAssign for KleeneValue {
    128    fn bitand_assign(&mut self, other: Self) {
    129        *self = *self & other;
    130    }
    131 }