use std::{fmt, collections::VecDeque, sync::Arc}; use futures::{Future, future::{ExecuteError, Executor}}; use futures_cpupool::CpuPool; use super::FilenameGenerator; #[derive(Clone, Debug, PartialEq)] pub enum NamePart { Map(String), Array, } impl NamePart { pub fn is_map(&self) -> bool { match *self { NamePart::Map(_) => true, _ => false, } } } #[derive(Clone)] pub enum FieldTerminator { File(Arc), Int, Float, Text, } impl fmt::Debug for FieldTerminator { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { FieldTerminator::File(_) => write!(f, "File(filename_generator)"), FieldTerminator::Int => write!(f, "Int"), FieldTerminator::Float => write!(f, "Float"), FieldTerminator::Text => write!(f, "Text"), } } } #[derive(Clone)] pub enum Field { Array(Array), File(Arc), Map(Map), Int, Float, Text, } impl fmt::Debug for Field { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Field::Array(ref arr) => write!(f, "Array({:?})", arr), Field::File(_) => write!(f, "File(filename_generator)"), Field::Map(ref map) => write!(f, "Map({:?})", map), Field::Int => write!(f, "Int"), Field::Float => write!(f, "Float"), Field::Text => write!(f, "Text"), } } } impl Field { pub fn file(gen: T) -> Self where T: FilenameGenerator + 'static, { Field::File(Arc::new(gen)) } pub fn text() -> Self { Field::Text } pub fn int() -> Self { Field::Int } pub fn float() -> Self { Field::Float } pub fn array(field: Field) -> Self { Field::Array(Array::new(field)) } pub fn map() -> Map { Map::new() } fn valid_field(&self, name: VecDeque) -> Option { trace!("Checking {:?} and {:?}", self, name); match *self { Field::Array(ref arr) => arr.valid_field(name), Field::Map(ref map) => map.valid_field(name), Field::File(ref gen) => if name.is_empty() { Some(FieldTerminator::File(Arc::clone(gen))) } else { None }, Field::Int => if name.is_empty() { Some(FieldTerminator::Int) } else { None }, Field::Float => if name.is_empty() { Some(FieldTerminator::Float) } else { None }, Field::Text => if name.is_empty() { Some(FieldTerminator::Text) } else { None }, } } } #[derive(Debug, Clone)] pub struct Array { inner: Box, } impl Array { fn new(field: Field) -> Self { Array { inner: Box::new(field), } } fn valid_field(&self, mut name: VecDeque) -> Option { trace!("Checking {:?} and {:?}", self, name); match name.pop_front() { Some(name_part) => match name_part { NamePart::Array => self.inner.valid_field(name), _ => None, }, None => None, } } } #[derive(Debug, Clone)] pub struct Map { inner: Vec<(String, Field)>, } impl Map { fn new() -> Self { Map { inner: Vec::new() } } pub fn field(mut self, key: &str, value: Field) -> Self { self.inner.push((key.to_owned(), value)); self } pub fn finalize(self) -> Field { Field::Map(self) } fn valid_field(&self, mut name: VecDeque) -> Option { trace!("Checking {:?} and {:?}", self, name); match name.pop_front() { Some(name_part) => match name_part { NamePart::Map(part_name) => self.inner .iter() .find(|(item, _)| *item == part_name) .and_then(|(_, field)| field.valid_field(name)), _ => None, }, None => None, } } } #[derive(Clone)] pub struct Form { pub max_fields: u32, pub max_field_size: u32, pub max_files: u32, pub max_file_size: u32, inner: Map, pub pool: ArcExecutor, } impl Form { pub fn new() -> Self { Form::from_executor(CpuPool::new_num_cpus()) } pub fn max_fields(mut self, max: u32) -> Self { self.max_fields = max; self } pub fn max_field_size(mut self, max: u32) -> Self { self.max_field_size = max; self } pub fn max_files(mut self, max: u32) -> Self { self.max_files = max; self } pub fn max_file_size(mut self, max: u32) -> Self { self.max_file_size = max; self } pub fn from_executor(executor: E) -> Self where E: Executor + Send>> + Send + Sync + Clone + 'static, { Form { max_fields: 100, max_field_size: 10_000, max_files: 20, max_file_size: 10_000_000, inner: Map::new(), pool: ArcExecutor::new(executor), } } pub fn field(mut self, name: &str, field: Field) -> Self { self.inner = self.inner.field(name, field); self } pub fn valid_field(&self, name: VecDeque) -> Option { self.inner.valid_field(name.clone()) } } impl fmt::Debug for Form { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Form({:?})", self.inner) } } #[derive(Clone)] pub struct ArcExecutor { inner: Arc + Send>> + Send + Sync + 'static>, } impl ArcExecutor { pub fn new(executor: E) -> Self where E: Executor + Send>> + Send + Sync + Clone + 'static, { ArcExecutor { inner: Arc::new(executor), } } } impl Executor + Send>> for ArcExecutor where { fn execute( &self, future: Box + Send>, ) -> Result<(), ExecuteError + Send>>> { self.inner.execute(future) } }