Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at:
https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
use crate::LengthHint;
impl core::ops::Add<LengthHint> for LengthHint {
type Output = Self;
fn add(self, other: LengthHint) -> Self {
LengthHint(
self.
0.saturating_add(other.
0),
match (self.
1, other.
1) {
(Some(c), Some(d)) => c.checked_add(d),
_ => None,
},
)
}
}
impl core::ops::AddAssign<LengthHint> for LengthHint {
fn add_assign(&mut self, other: Self) {
*self = *self + other;
}
}
impl core::iter::Sum<LengthHint> for LengthHint {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = LengthHint>,
{
iter.fold(LengthHint::exact(
0), core::ops::Add::add)
}
}
impl core::ops::Add<usize> for LengthHint {
type Output = Self;
fn add(self, other: usize) -> Self {
Self(
self.
0.saturating_add(other),
self.
1.and_then(|upper| upper.checked_add(other)),
)
}
}
impl core::ops::AddAssign<usize> for LengthHint {
fn add_assign(&mut self, other: usize) {
*self = *self + other;
}
}
impl core::ops::Mul<usize> for LengthHint {
type Output = Self;
fn mul(self, other: usize) -> Self {
Self(
self.
0.saturating_mul(other),
self.
1.and_then(|upper| upper.checked_mul(other)),
)
}
}
impl core::ops::MulAssign<usize> for LengthHint {
fn mul_assign(&mut self, other: usize) {
*self = *self * other;
}
}
impl core::ops::BitOr<LengthHint> for LengthHint {
type Output = Self;
/// Returns a new hint that is correct wherever `self` is correct, and wherever
/// `other` is correct.
///
/// Example:
/// ```
/// # use writeable::{LengthHint, Writeable};
/// # use core::fmt;
/// # fn coin_flip() -> bool { true }
///
/// struct NonDeterministicWriteable(String, String);
///
/// impl Writeable for NonDeterministicWriteable {
/// fn write_to<W: fmt::Write + ?Sized>(
/// &self,
/// sink: &mut W,
/// ) -> fmt::Result {
/// sink.write_str(if coin_flip() { &self.
0 } else { &self.
1 })
/// }
///
/// fn writeable_length_hint(&self) -> LengthHint {
/// LengthHint::exact(self.
0.len()) | LengthHint::exact(self.
1.len())
/// }
/// }
///
/// writeable::impl_display_with_writeable!(NonDeterministicWriteable);
/// ```
fn bitor(self, other: LengthHint) -> Self {
LengthHint(
Ord::min(self.
0, other.
0),
match (self.
1, other.
1) {
(Some(c), Some(d)) => Some(Ord::max(c, d)),
_ => None,
},
)
}
}
impl core::ops::BitOrAssign<LengthHint> for LengthHint {
fn bitor_assign(&mut self, other: Self) {
*self = *self | other;
}
}
impl core::iter::Sum<usize> for LengthHint {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = usize>,
{
LengthHint::exact(iter.sum::<usize>())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(LengthHint::exact(
3) +
2, LengthHint::exact(
5));
assert_eq!(
LengthHint::exact(
3) + LengthHint::exact(
2),
LengthHint::exact(
5)
);
assert_eq!(
LengthHint::exact(
3) + LengthHint::undefined(),
LengthHint::at_least(
3)
);
assert_eq!(LengthHint::undefined() +
2, LengthHint::at_least(
2));
assert_eq!(
LengthHint::undefined() + LengthHint::exact(
2),
LengthHint::at_least(
2)
);
assert_eq!(
LengthHint::undefined() + LengthHint::undefined(),
LengthHint::undefined()
);
assert_eq!(
LengthHint::at_least(
15) + LengthHint::exact(
3),
LengthHint::at_least(
18)
);
assert_eq!(
LengthHint::at_least(
15) + LengthHint::at_most(
3),
LengthHint::at_least(
15)
);
assert_eq!(LengthHint::between(
48,
92) +
5, LengthHint::between(
53,
97));
let mut len = LengthHint::exact(
5);
len += LengthHint::exact(
3);
assert_eq!(len, LengthHint::exact(
8));
len +=
2;
assert_eq!(len, LengthHint::exact(
10));
len += LengthHint::undefined();
assert_eq!(len, LengthHint::at_least(
10));
len += LengthHint::exact(
3);
assert_eq!(len, LengthHint::at_least(
13));
len +=
2;
assert_eq!(len, LengthHint::at_least(
15));
len += LengthHint::undefined();
assert_eq!(len, LengthHint::at_least(
15));
assert_eq!(
LengthHint::between(usize::MAX -
10, usize::MAX -
5) + LengthHint::exact(
20),
LengthHint::at_least(usize::MAX)
);
}
#[test]
fn test_sum() {
let lens = [
LengthHint::exact(
4),
LengthHint::exact(
1),
LengthHint::exact(
1),
];
assert_eq!(
lens.iter().copied().sum::<LengthHint>(),
LengthHint::exact(
6)
);
let lens = [
LengthHint::exact(
4),
LengthHint::undefined(),
LengthHint::at_least(
1),
];
assert_eq!(
lens.iter().copied().sum::<LengthHint>(),
LengthHint::at_least(
5)
);
let lens = [
LengthHint::exact(
4),
LengthHint::undefined(),
LengthHint::at_most(
1),
];
assert_eq!(
lens.iter().copied().sum::<LengthHint>(),
LengthHint::at_least(
4)
);
let lens = [
4,
1,
1];
assert_eq!(
lens.iter().copied().sum::<LengthHint>(),
LengthHint::exact(
6)
);
}
#[test]
fn test_mul() {
assert_eq!(LengthHint::exact(
3) *
2, LengthHint::exact(
6));
assert_eq!(LengthHint::undefined() *
2, LengthHint::undefined());
assert_eq!(
LengthHint::between(
48,
92) *
2,
LengthHint::between(
96,
184)
);
let mut len = LengthHint::exact(
5);
len *=
2;
assert_eq!(len, LengthHint::exact(
10));
assert_eq!(
LengthHint::between(usize::MAX -
10, usize::MAX -
5) *
2,
LengthHint::at_least(usize::MAX)
);
}
#[test]
fn test_bitor() {
assert_eq!(
LengthHint::exact(
3) | LengthHint::exact(
2),
LengthHint::between(
2,
3)
);
assert_eq!(
LengthHint::exact(
3) | LengthHint::undefined(),
LengthHint::undefined()
);
assert_eq!(
LengthHint::undefined() | LengthHint::undefined(),
LengthHint::undefined()
);
assert_eq!(
LengthHint::exact(
10) | LengthHint::exact(
10),
LengthHint::exact(
10)
);
assert_eq!(
LengthHint::at_least(
15) | LengthHint::exact(
3),
LengthHint::at_least(
3)
);
assert_eq!(
LengthHint::at_least(
15) | LengthHint::at_most(
18),
LengthHint::undefined()
);
assert_eq!(
LengthHint::at_least(
15) | LengthHint::at_least(
18),
LengthHint::at_least(
15)
);
assert_eq!(
LengthHint::at_most(
15) | LengthHint::at_most(
18),
LengthHint::at_most(
18)
);
assert_eq!(
LengthHint::between(
5,
10) | LengthHint::at_most(
3),
LengthHint::at_most(
10)
);
let mut len = LengthHint::exact(
5);
len |= LengthHint::exact(
3);
assert_eq!(len, LengthHint::between(
5,
3));
}
}