httpsig/message_component/
component_id.rs1use super::{
2 component_name::{DerivedComponentName, HttpMessageComponentName},
3 component_param::{HttpMessageComponentParam, HttpMessageComponentParams},
4};
5use crate::error::{HttpSigError, HttpSigResult};
6use sfv::Parser;
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct HttpMessageComponentId {
12 pub name: HttpMessageComponentName,
14 pub params: HttpMessageComponentParams,
16}
17
18impl HttpMessageComponentId {
19 pub fn add_req_param(&mut self) {
21 self.params.0.insert(HttpMessageComponentParam::Req);
22 }
23}
24
25impl std::fmt::Display for HttpMessageComponentId {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "{}{}", self.name, self.params)
28 }
29}
30
31impl TryFrom<&str> for HttpMessageComponentId {
32 type Error = HttpSigError;
33 fn try_from(val: &str) -> HttpSigResult<Self> {
37 let val = val.trim();
38 let item: sfv::Item = if !val.starts_with('"') && !val.ends_with('"') && !val.is_empty() && !val.contains('"') {
39 Parser::new(format!("\"{val}\"").as_str())
41 .parse()
42 .map_err(|e| HttpSigError::ParseSFVError(e.to_string()))?
43 } else {
45 Parser::new(val)
46 .parse()
47 .map_err(|e| HttpSigError::ParseSFVError(e.to_string()))?
48 };
50
51 let res = Self {
52 name: HttpMessageComponentName::try_from(&item.bare_item)?,
53 params: HttpMessageComponentParams::try_from(&item.params)?,
54 };
55
56 if res.params.0.iter().any(|v| matches!(v, &HttpMessageComponentParam::Name(_)))
58 && !matches!(res.name, HttpMessageComponentName::Derived(DerivedComponentName::QueryParam))
59 {
60 return Err(HttpSigError::InvalidComponentId(format!(
61 "Invalid http message component id: {res}"
62 )));
63 }
64
65 if res.params.0.iter().any(|v| {
68 matches!(v, &HttpMessageComponentParam::Bs)
69 || matches!(v, &HttpMessageComponentParam::Sf)
70 || matches!(v, &HttpMessageComponentParam::Tr)
71 || matches!(v, &HttpMessageComponentParam::Key(_))
72 }) && !matches!(res.name, HttpMessageComponentName::HttpField(_))
73 {
74 return Err(HttpSigError::InvalidComponentId(format!(
75 "Invalid http message component id: {res}"
76 )));
77 }
78
79 Ok(res)
80 }
81}