xidl_parser/hir/annotation/
location.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5pub enum HttpParameterLocation {
6 Header,
8 Query,
10 Cookie,
12}
13
14impl HttpParameterLocation {
15 pub fn parse(value: &str) -> Option<Self> {
17 match value.to_ascii_lowercase().as_str() {
18 "header" => Some(Self::Header),
19 "query" => Some(Self::Query),
20 "cookie" => Some(Self::Cookie),
21 _ => None,
22 }
23 }
24
25 pub fn as_str(self) -> &'static str {
27 match self {
28 Self::Header => "header",
29 Self::Query => "query",
30 Self::Cookie => "cookie",
31 }
32 }
33
34 pub fn names_equal(self, first: &str, second: &str) -> bool {
36 match self {
37 Self::Header => first.eq_ignore_ascii_case(second),
38 Self::Query | Self::Cookie => first == second,
39 }
40 }
41
42 pub fn valid_name(self, name: &str) -> bool {
44 match self {
45 Self::Header | Self::Cookie => http::HeaderName::from_bytes(name.as_bytes()).is_ok(),
46 Self::Query => !name.is_empty() && !name.chars().any(char::is_control),
47 }
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct VersionParameter {
54 pub location: HttpParameterLocation,
56 pub name: String,
58}
59
60impl VersionParameter {
61 pub(crate) fn validate_value(&self, value: &str) -> Result<(), String> {
62 if self.location == HttpParameterLocation::Header {
63 if value.trim_matches([' ', '\t']) != value {
64 return Err(
65 "version header value cannot start or end with HTTP whitespace".to_string(),
66 );
67 }
68 let header = http::HeaderValue::from_str(value)
69 .map_err(|error| format!("invalid version header value: {error}"))?;
70 header
71 .to_str()
72 .map_err(|error| format!("version header value must be visible ASCII: {error}"))?;
73 }
74 Ok(())
75 }
76}