http_msgsign/components/
field.rs1use 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
23impl 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}