/*
* This file is part of Actix Form Data.
*
* Copyright © 2020 Riley Trautman
*
* Actix Form Data is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Actix Form Data is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Actix Form Data. If not, see .
*/
use crate::{
error::Error,
types::{
ContentDisposition, FieldTerminator, FileFn, FileMeta, Form, MultipartContent,
MultipartForm, MultipartHash, NamePart, Value,
},
};
use actix_web::web::BytesMut;
use std::{collections::HashMap, future::poll_fn, path::Path, pin::Pin, rc::Rc};
use tokio::{sync::mpsc::Receiver, task::JoinSet};
use tracing::trace;
struct Streamer(S, bool);
impl Streamer
where
S: futures_core::Stream + Unpin,
{
async fn next(&mut self) -> Option {
if self.1 {
return None;
}
let opt = poll_fn(|cx| Pin::new(&mut self.0).poll_next(cx)).await;
self.1 = opt.is_none();
opt
}
}
struct ReceiverStream(Receiver);
impl futures_core::Stream for ReceiverStream {
type Item = T;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll