1use std::{
4 fmt,
5 ops::{Deref, DerefMut},
6};
7
8use serde::de::DeserializeOwned;
9
10use crate::{FromRequest, Request, RequestExt, Result};
11
12use super::{Payload, PayloadError};
13
14pub struct Form<T = ()>(pub T);
16
17impl<T> Form<T> {
18 #[inline]
20 pub const fn new(data: T) -> Self {
21 Self(data)
22 }
23
24 #[inline]
26 pub fn into_inner(self) -> T {
27 self.0
28 }
29}
30
31impl<T> Clone for Form<T>
32where
33 T: Clone,
34{
35 fn clone(&self) -> Self {
36 Self(self.0.clone())
37 }
38}
39
40impl<T> AsRef<T> for Form<T> {
41 fn as_ref(&self) -> &T {
42 &self.0
43 }
44}
45
46impl<T> Deref for Form<T> {
47 type Target = T;
48
49 fn deref(&self) -> &T {
50 &self.0
51 }
52}
53
54impl<T> DerefMut for Form<T> {
55 fn deref_mut(&mut self) -> &mut T {
56 &mut self.0
57 }
58}
59
60impl<T> fmt::Debug for Form<T>
61where
62 T: fmt::Debug,
63{
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 T::fmt(self, f)
66 }
67}
68
69impl<T> Payload for Form<T> {
70 const NAME: &'static str = "form";
71
72 const LIMIT: u64 = 1024 * 32;
74
75 fn detect(m: &mime::Mime) -> bool {
76 m.type_() == mime::APPLICATION && m.subtype() == mime::WWW_FORM_URLENCODED
77 }
78
79 fn mime() -> mime::Mime {
80 mime::APPLICATION_WWW_FORM_URLENCODED
81 }
82}
83
84impl<T> FromRequest for Form<T>
85where
86 T: DeserializeOwned,
87{
88 type Error = PayloadError;
89
90 #[inline]
91 async fn extract(req: &mut Request) -> Result<Self, Self::Error> {
92 req.form().await.map(Self)
93 }
94}