<% def make_type(it) case it[:type] when "integer" then "u64" when "unixtimestamp" then "DateTime" else "String" end end %>use chrono::prelude::*; use std::collections::HashMap; <% yml[:keys].each do |it| %>const <%= it[:name].gsub(/-/, "_").upcase %>: &str = "<%= it[:name] %>"; <% end %> const KEYS: [&str; <%= yml[:keys].count %>] = [<% yml[:keys].each do |it| %> <%= it[:name].gsub(/-/, "_").upcase %>,<% end %> ]; #[derive(Debug, Clone)] pub struct Headers {<% yml[:keys].each do |it| %> pub <%= it[:name].gsub(/-/, "_").downcase %>: Option<<%= make_type(it) %>>,<% end %> pub extra: HashMap, } impl Headers { pub fn new(header: &reqwest::header::HeaderMap) -> Self { let mut extra = HashMap::new(); for (name, value) in header.iter() { if !KEYS.contains(&name.as_str()) { if let Ok(value) = value.to_str() { extra.insert(name.as_str().to_string(), value.to_string()); } } } Self {<% yml[:keys].each do |it| %> <%= it[:name].gsub(/-/, "_").downcase %>: get_<%= it[:type] %>_value(header, <%= it[:name].gsub(/-/, "_").upcase %>),<% end %> extra, } } } impl std::fmt::Display for Headers { // This trait requires `fmt` with this exact signature. // このトレイトは`fmt`が想定通りのシグネチャであることを要求します。 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:?}", self) } } fn get_integer_value(header: &reqwest::header::HeaderMap, key: &str) -> Option { let Some(res) = header.get(key) else { return None; }; let Ok(res) = res.to_str() else { return None; }; res.parse().ok() } fn get_string_value(header: &reqwest::header::HeaderMap, key: &str) -> Option { let Some(res) = header.get(key) else { return None; }; res.to_str().ok().map(|it| it.to_string()) } fn get_unixtimestamp_value(header: &reqwest::header::HeaderMap, key: &str) -> Option> { let Some(res) = get_integer_value(header, key) else { return None; }; Utc.timestamp_opt(res as i64, 0).single() }