Skip to main content

twapi_v2/
headers.rs

1use chrono::prelude::*;
2use std::collections::HashMap;
3
4const X_ACCESS_LEVEL: &str = "x-access-level";
5const X_APP_LIMIT_24HOUR_LIMIT: &str = "x-app-limit-24hour-limit";
6const X_APP_LIMIT_24HOUR_RESET: &str = "x-app-limit-24hour-reset";
7const X_APP_LIMIT_24HOUR_REMAINING: &str = "x-app-limit-24hour-remaining";
8const X_CONNECTION_HASH: &str = "x-connection-hash";
9const X_CONTENT_TYPE_OPTIONS: &str = "x-content-type-options";
10const X_FRAME_OPTIONS: &str = "x-frame-options";
11const X_RATE_LIMIT_LIMIT: &str = "x-rate-limit-limit";
12const X_RATE_LIMIT_RESET: &str = "x-rate-limit-reset";
13const X_RATE_LIMIT_REMAINING: &str = "x-rate-limit-remaining";
14const X_RESPONSE_TIME: &str = "x-response-time";
15const X_TRANSACTION_ID: &str = "x-transaction-id";
16const X_USER_LIMIT_24HOUR_LIMIT: &str = "x-user-limit-24hour-limit";
17const X_USER_LIMIT_24HOUR_RESET: &str = "x-user-limit-24hour-reset";
18const X_USER_LIMIT_24HOUR_REMAINING: &str = "x-user-limit-24hour-remaining";
19const X_XSS_PROTECTION: &str = "x-xss-protection";
20
21const KEYS: [&str; 16] = [
22    X_ACCESS_LEVEL,
23    X_APP_LIMIT_24HOUR_LIMIT,
24    X_APP_LIMIT_24HOUR_RESET,
25    X_APP_LIMIT_24HOUR_REMAINING,
26    X_CONNECTION_HASH,
27    X_CONTENT_TYPE_OPTIONS,
28    X_FRAME_OPTIONS,
29    X_RATE_LIMIT_LIMIT,
30    X_RATE_LIMIT_RESET,
31    X_RATE_LIMIT_REMAINING,
32    X_RESPONSE_TIME,
33    X_TRANSACTION_ID,
34    X_USER_LIMIT_24HOUR_LIMIT,
35    X_USER_LIMIT_24HOUR_RESET,
36    X_USER_LIMIT_24HOUR_REMAINING,
37    X_XSS_PROTECTION,
38];
39
40#[derive(Debug, Clone)]
41pub struct Headers {
42    pub x_access_level: Option<String>,
43    pub x_app_limit_24hour_limit: Option<u64>,
44    pub x_app_limit_24hour_reset: Option<DateTime<Utc>>,
45    pub x_app_limit_24hour_remaining: Option<u64>,
46    pub x_connection_hash: Option<String>,
47    pub x_content_type_options: Option<String>,
48    pub x_frame_options: Option<String>,
49    pub x_rate_limit_limit: Option<u64>,
50    pub x_rate_limit_reset: Option<DateTime<Utc>>,
51    pub x_rate_limit_remaining: Option<u64>,
52    pub x_response_time: Option<u64>,
53    pub x_transaction_id: Option<String>,
54    pub x_user_limit_24hour_limit: Option<u64>,
55    pub x_user_limit_24hour_reset: Option<DateTime<Utc>>,
56    pub x_user_limit_24hour_remaining: Option<u64>,
57    pub x_xss_protection: Option<u64>,
58    pub extra: HashMap<String, String>,
59}
60
61impl Headers {
62    pub fn new(header: &reqwest::header::HeaderMap) -> Self {
63        let mut extra = HashMap::new();
64        for (name, value) in header.iter() {
65            if !KEYS.contains(&name.as_str())
66                && let Ok(value) = value.to_str()
67            {
68                extra.insert(name.as_str().to_string(), value.to_string());
69            }
70        }
71        Self {
72            x_access_level: get_string_value(header, X_ACCESS_LEVEL),
73            x_app_limit_24hour_limit: get_integer_value(header, X_APP_LIMIT_24HOUR_LIMIT),
74            x_app_limit_24hour_reset: get_unixtimestamp_value(header, X_APP_LIMIT_24HOUR_RESET),
75            x_app_limit_24hour_remaining: get_integer_value(header, X_APP_LIMIT_24HOUR_REMAINING),
76            x_connection_hash: get_string_value(header, X_CONNECTION_HASH),
77            x_content_type_options: get_string_value(header, X_CONTENT_TYPE_OPTIONS),
78            x_frame_options: get_string_value(header, X_FRAME_OPTIONS),
79            x_rate_limit_limit: get_integer_value(header, X_RATE_LIMIT_LIMIT),
80            x_rate_limit_reset: get_unixtimestamp_value(header, X_RATE_LIMIT_RESET),
81            x_rate_limit_remaining: get_integer_value(header, X_RATE_LIMIT_REMAINING),
82            x_response_time: get_integer_value(header, X_RESPONSE_TIME),
83            x_transaction_id: get_string_value(header, X_TRANSACTION_ID),
84            x_user_limit_24hour_limit: get_integer_value(header, X_USER_LIMIT_24HOUR_LIMIT),
85            x_user_limit_24hour_reset: get_unixtimestamp_value(header, X_USER_LIMIT_24HOUR_RESET),
86            x_user_limit_24hour_remaining: get_integer_value(header, X_USER_LIMIT_24HOUR_REMAINING),
87            x_xss_protection: get_integer_value(header, X_XSS_PROTECTION),
88            extra,
89        }
90    }
91}
92
93impl std::fmt::Display for Headers {
94    // This trait requires `fmt` with this exact signature.
95    // このトレイトは`fmt`が想定通りのシグネチャであることを要求します。
96    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
97        write!(f, "{:?}", self)
98    }
99}
100
101fn get_integer_value(header: &reqwest::header::HeaderMap, key: &str) -> Option<u64> {
102    header.get(key)?.to_str().ok()?.parse().ok()
103}
104
105fn get_string_value(header: &reqwest::header::HeaderMap, key: &str) -> Option<String> {
106    header.get(key)?.to_str().ok().map(|it| it.to_string())
107}
108
109fn get_unixtimestamp_value(
110    header: &reqwest::header::HeaderMap,
111    key: &str,
112) -> Option<DateTime<Utc>> {
113    let res = get_integer_value(header, key)?;
114    Utc.timestamp_opt(res as i64, 0).single()
115}