#[derive(Debug, Copy, Clone)]
pub struct N {
pub written: u64,
pub complete: bool,
}
impl std::fmt::Display for N {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.written.fmt(f)
}
}
impl std::ops::Deref for N {
type Target = u64;
fn deref(&self) -> &Self::Target {
&self.written
}
}
#[derive(Debug, Copy, Clone)]
pub struct Capped<T> {
pub value: T,
pub n: N
}
impl<T> Capped<T> {
#[inline(always)]
pub fn new(value: T, n: N) -> Self {
Capped { value, n, }
}
#[inline(always)]
pub fn complete(value: T, len: usize) -> Self {
Capped { value, n: N { written: len as u64, complete: true } }
}
#[inline(always)]
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Capped<U> {
Capped { value: f(self.value), n: self.n }
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.n.written == 0
}
#[inline(always)]
pub fn is_complete(&self) -> bool {
self.n.complete
}
#[inline(always)]
pub fn into_inner(self) -> T {
self.value
}
}
impl<T> std::ops::Deref for Capped<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T> std::ops::DerefMut for Capped<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
impl<T: AsRef<[u8]>> From<T> for Capped<T> {
fn from(value: T) -> Self {
let len = value.as_ref().len();
Capped::complete(value, len)
}
}
use crate::response::{self, Responder};
use crate::request::Request;
impl<'r, 'o: 'r, T: Responder<'r, 'o>> Responder<'r, 'o> for Capped<T> {
fn respond_to(self, request: &'r Request<'_>) -> response::Result<'o> {
self.value.respond_to(request)
}
}
macro_rules! impl_strict_from_form_field_from_capped {
($T:ty) => (const _: () = {
use $crate::form::{FromFormField, ValueField, DataField, Result};
use $crate::data::Capped;
#[crate::async_trait]
impl<'v> FromFormField<'v> for $T {
fn default() -> Option<Self> {
<Capped<$T> as FromFormField<'v>>::default().map(|c| c.value)
}
fn from_value(f: ValueField<'v>) -> Result<'v, Self> {
let capped = <Capped<$T> as FromFormField<'v>>::from_value(f)?;
if !capped.is_complete() {
Err((None, Some(capped.n.written)))?;
}
Ok(capped.value)
}
async fn from_data(field: DataField<'v, '_>) -> Result<'v, Self> {
let capped = <Capped<$T> as FromFormField<'v>>::from_data(field);
let capped = capped.await?;
if !capped.is_complete() {
Err((None, Some(capped.n.written)))?;
}
Ok(capped.value)
}
}
};)
}
macro_rules! impl_strict_from_data_from_capped {
($T:ty) => (
#[crate::async_trait]
impl<'r> $crate::data::FromData<'r> for $T {
type Error = <$crate::data::Capped<Self> as $crate::data::FromData<'r>>::Error;
async fn from_data(
r: &'r $crate::Request<'_>,
d: $crate::Data<'r>
) -> $crate::data::Outcome<'r, Self> {
use $crate::outcome::Outcome::*;
use std::io::{Error, ErrorKind::UnexpectedEof};
match <$crate::data::Capped<$T> as FromData>::from_data(r, d).await {
Success(p) if p.is_complete() => Success(p.into_inner()),
Success(_) => {
let e = Error::new(UnexpectedEof, "data limit exceeded");
Failure((Status::BadRequest, e.into()))
},
Forward(d) => Forward(d),
Failure((s, e)) => Failure((s, e)),
}
}
}
)
}