Skip to main content

http_msgsign/components/
field.rs

1use std::fmt::{Display, Formatter};
2
3use http::{Request, Response};
4
5use crate::components::params::{FieldParameter, Serializer};
6use crate::components::values::Value;
7use crate::components::{HttpComponent, NameType};
8use crate::errors::{HttpComponentError, InvalidFormat, InvalidSerializer};
9use crate::sign::ExchangeRecord;
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash)]
12pub struct TargetField {
13    name: NameType,
14    params: Serializer,
15}
16
17impl Display for TargetField {
18    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
19        write!(f, "{}{}", self.name, self.params)
20    }
21}
22
23// noinspection DuplicatedCode
24impl TargetField {
25    pub fn new(name: NameType, params: FieldParameter) -> Result<Self, InvalidSerializer> {
26        Ok(Self {
27            name,
28            params: params.into_serializer()?,
29        })
30    }
31
32    pub(crate) fn seek_request<B>(
33        &self,
34        request: &Request<B>,
35    ) -> Result<HttpComponent, HttpComponentError> {
36        if self.params.require_request() {
37            return Err(HttpComponentError::InvalidDataType {
38                expect: "response with request",
39            });
40        }
41
42        match &self.name {
43            NameType::Derived(derive) => Ok(HttpComponent {
44                id: self.to_string(),
45                value: derive.seek_request(request, &self.params)?,
46            }),
47            NameType::Field(target) => {
48                let val = Value::from_header(target, request.headers())
49                    .serialize(&self.params)?;
50                Ok(HttpComponent {
51                    id: self.to_string(),
52                    value: Some(val),
53                })
54            }
55        }
56    }
57
58    pub(crate) fn seek_response<B>(
59        &self,
60        response: &Response<B>,
61    ) -> Result<HttpComponent, HttpComponentError> {
62        if self.params.require_request() {
63            return Err(HttpComponentError::InvalidDataType {
64                expect: "response with request",
65            });
66        }
67
68        match &self.name {
69            NameType::Derived(derive) => Ok(HttpComponent {
70                id: self.to_string(),
71                value: derive.seek_response(response)?,
72            }),
73            NameType::Field(target) => {
74                let val = Value::from_header(target, response.headers())
75                    .serialize(&self.params)?;
76                Ok(HttpComponent {
77                    id: self.to_string(),
78                    value: Some(val),
79                })
80            }
81        }
82    }
83
84    pub(crate) fn seek_record<Req, Res>(
85        &self,
86        ExchangeRecord { request, response }: &ExchangeRecord<Req, Res>,
87    ) -> Result<HttpComponent, HttpComponentError> {
88        if self.params.require_request() {
89            match &self.name {
90                NameType::Derived(derive) => Ok(HttpComponent {
91                    id: self.to_string(),
92                    value: derive.seek_request(request, &self.params)?,
93                }),
94                NameType::Field(target) => {
95                    let val = Value::from_header(target, request.headers())
96                        .serialize(&self.params)?;
97                    Ok(HttpComponent {
98                        id: self.to_string(),
99                        value: Some(val),
100                    })
101                }
102            }
103        } else {
104            match &self.name {
105                NameType::Derived(derive) => Ok(HttpComponent {
106                    id: self.to_string(),
107                    value: derive.seek_response(response)?,
108                }),
109                NameType::Field(target) => {
110                    let val = Value::from_header(target, response.headers())
111                        .serialize(&self.params)?;
112                    Ok(HttpComponent {
113                        id: self.to_string(),
114                        value: Some(val),
115                    })
116                }
117            }
118        }
119    }
120}
121
122impl TryFrom<sfv::Item> for TargetField {
123    type Error = InvalidFormat;
124
125    fn try_from(sfv::Item { bare_item, params }: sfv::Item) -> Result<Self, Self::Error> {
126        Ok(Self {
127            name: NameType::try_from(bare_item)?,
128            params: Serializer::try_from(params).unwrap(),
129        })
130    }
131}