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
//!Yukikaze-sama utilities.
use core::mem;
use std::io::{self, Write};

const DEFAULT_CAPACITY: usize = 4096;
const SMOL_CAPCITY: usize = 64;

#[macro_export]
///Await future in async context.
///
///Because `.await` is retarded.
macro_rules! matsu {
    ($exp:expr) => {
        ($exp).await
    }
}

#[doc(hidden)]
#[macro_export]
#[cfg(not(debug_assertions))]
macro_rules! unreach {
    () => ({
        unsafe {
            std::hint::unreachable_unchecked();
        }
    })
}

#[doc(hidden)]
#[macro_export]
#[cfg(debug_assertions)]
macro_rules! unreach {
    () => ({
        unreachable!()
    })
}

pub mod fut;
pub mod enc;

///Option extensions
pub trait OptionExt<T> {
    ///Unwraps, assuming `None` is impossible
    fn unreach_none(self) -> T;
}

impl<T> OptionExt<T> for Option<T> {
    fn unreach_none(self) -> T {
        match self {
            Some(val) => val,
            None => unreach!(),
        }
    }
}

///Convenience wrapper over `bytes::BytesMut`
///
///Provides `io::Write` that automatically resizes.
pub struct BytesWriter {
    buf: bytes::BytesMut,
}

impl BytesWriter {
    ///Creates new instance with default capacity 4096
    #[inline]
    pub fn new() -> Self {
        Self::with_capacity(DEFAULT_CAPACITY)
    }

    #[inline]
    ///Creates new instance with smol capacity 64
    pub fn with_smol_capacity() -> Self {
        Self::with_capacity(SMOL_CAPCITY)
    }

    #[inline]
    ///Creates new instance with provided capacity
    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            buf: bytes::BytesMut::with_capacity(capacity)
        }
    }

    #[inline]
    ///Converts into underlying `bytes::BytesMut`
    pub fn into_inner(self) -> bytes::BytesMut {
        self.buf
    }

    #[inline]
    ///Converts into `bytes::Bytes`
    pub fn freeze(&mut self) -> bytes::Bytes {
        mem::replace(&mut self.buf, bytes::BytesMut::new()).freeze()
    }

    #[inline]
    ///Returns buffer length.
    pub fn len(&self) -> usize {
        self.buf.len()
    }

    #[inline]
    ///Splits off, the same as `bytes::BytesMut::split_off`
    pub fn split_off(&mut self, at: usize) -> Self {
        Self {
            buf: self.buf.split_off(at)
        }
    }

    #[inline]
    ///Reserve extra memory, the same as `bytes::BytesMut::reserve`
    pub fn reserve(&mut self, add: usize) {
        self.buf.reserve(add);
    }
}

impl io::Write for BytesWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.buf.extend_from_slice(buf);
        Ok(buf.len())
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.buf.extend_from_slice(buf);
        Ok(())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

///Converts integer to header's value.
pub fn content_len_value(len: u64) -> crate::http::header::HeaderValue {
    let mut res = BytesWriter::with_capacity(1);
    let _ = write!(&mut res, "{}", len);
    unsafe { crate::http::header::HeaderValue::from_maybe_shared_unchecked(res.freeze()) }
}