http_body_alt/
size_hint.rs1use std::ops::Add;
2
3#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
11pub enum SizeHint {
12 None,
16 Exact(u64),
22 #[default]
24 Unknown,
25}
26
27impl Add for SizeHint {
28 type Output = Self;
29
30 fn add(self, rhs: Self) -> Self::Output {
31 match (self, rhs) {
32 (Self::None, Self::None) => Self::None,
33 (Self::None, Self::Exact(size)) => Self::Exact(size),
34 (Self::Exact(size), Self::None) => Self::Exact(size),
35 (Self::Exact(size1), Self::Exact(size2)) => size1.checked_add(size2).map_or(Self::Unknown, Self::Exact),
36 _ => Self::Unknown,
37 }
38 }
39}
40
41impl SizeHint {
42 pub const NO_BODY_HINT: (usize, Option<usize>) = (usize::MAX, Some(0));
46
47 pub(crate) fn exact<U>(size: U) -> Self
48 where
49 u64: TryFrom<U>,
50 <u64 as TryFrom<U>>::Error: core::fmt::Debug,
51 {
52 SizeHint::Exact(u64::try_from(size).unwrap())
53 }
54
55 pub(crate) fn as_stream_size_hint(&self) -> (usize, Option<usize>) {
56 match self {
57 Self::Exact(len) => {
58 let len = usize::try_from(*len).unwrap();
59 (len, Some(len))
60 }
61 Self::Unknown => (0, None),
62 Self::None => Self::NO_BODY_HINT,
63 }
64 }
65
66 pub(crate) fn from_stream_size_hint(hint: (usize, Option<usize>)) -> Self {
67 match hint {
68 Self::NO_BODY_HINT => Self::None,
69 (low, Some(up)) if low == up => Self::exact(low),
70 _ => Self::Unknown,
71 }
72 }
73}