1use std::{collections::HashMap, path::PathBuf};
2
3use async_tempfile::TempFile;
4
5#[derive(Debug)]
6pub struct FileField {
7 pub name: String,
8 temp_file: TempFile,
9 pub temp_path: PathBuf,
10}
11
12impl FileField {
13 pub fn from<S: AsRef<str>>(name: S, temp_file: TempFile) -> Self {
14 let temp_path = temp_file.file_path().clone();
15
16 Self {
17 name: name.as_ref().to_string(),
18 temp_file,
19 temp_path,
20 }
21 }
22
23 pub fn temp_file(&self) -> &TempFile {
24 &self.temp_file
25 }
26}
27
28pub type Files = HashMap<String, Vec<FileField>>;
29pub type FormData = HashMap<String, Vec<String>>;
30
31pub trait FileFieldShortcut {
32 fn value<S: AsRef<str>>(&self, name: S) -> Option<&FileField>;
34}
35
36impl FileFieldShortcut for Files {
37 fn value<S: AsRef<str>>(&self, name: S) -> Option<&FileField> {
38 let name = name.as_ref();
39
40 for (key, values) in self.iter() {
41 if key.to_lowercase() != name.to_lowercase() {
42 continue;
43 }
44
45 if let Some(field) = values.get(0) {
46 return Some(field);
47 }
48 }
49 None
50 }
51}
52
53pub struct FormConstraints {
68 max_body_size: usize,
70 max_header_size: usize,
72 max_file_size: usize,
74 max_value_size: usize,
76 custom_max_sizes: HashMap<String, usize>,
78}
79
80impl FormConstraints {
81 pub fn new(
82 max_body_size: usize,
83 max_header_size: usize,
84 max_file_size: usize,
85 max_value_size: usize,
86 custom_max_sizes: HashMap<String, usize>,
87 ) -> Self {
88 Self {
89 max_body_size,
90 max_header_size,
91 max_file_size,
92 max_value_size,
93 custom_max_sizes,
94 }
95 }
96
97 pub fn max_body_size(&self, buffer_size: usize) -> usize {
98 if buffer_size > self.max_body_size {
99 return buffer_size;
100 }
101
102 self.max_body_size
104 }
105
106 pub fn max_header_size(&self, buffer_size: usize) -> usize {
107 if buffer_size > self.max_header_size {
108 return buffer_size;
109 }
110
111 self.max_header_size
113 }
114
115 pub fn max_value_size(&self, buffer_size: usize) -> usize {
116 if buffer_size > self.max_value_size {
117 return buffer_size;
118 }
119
120 self.max_value_size
122 }
123 pub fn max_size_for_field(&self, field_name: &String, buffer_size: usize) -> usize {
124 if let Some(max_size) = self.custom_max_sizes.get(field_name) {
125 if buffer_size > *max_size {
126 return buffer_size;
127 }
128 return max_size.to_owned();
129 }
130
131 return self.max_value_size;
133 }
134
135 pub fn max_size_for_file(&self, field_name: &String, buffer_size: usize) -> usize {
136 if let Some(max_size) = self.custom_max_sizes.get(field_name) {
137 if buffer_size > *max_size {
138 return buffer_size;
139 }
140 return max_size.to_owned();
141 }
142
143 return self.max_file_size;
145 }
146}
147
148#[derive(Debug)]
149pub enum FormFieldError {
150 MaxBodySizeExceed,
152 MaxHeaderSizeExceed,
154 MaxFileSizeExceed(String),
156 MaxValueSizeExceed(String),
158 Others(Option<String>, String, bool),
161}