recipes/backend/src/utils.rs

82 lines
2.2 KiB
Rust

use std::net::SocketAddr;
use axum::http::HeaderMap;
use crate::consts;
pub fn get_ip_and_user_agent(headers: &HeaderMap, remote_address: SocketAddr) -> (String, String) {
let ip = match headers.get(consts::REVERSE_PROXY_IP_HTTP_FIELD) {
Some(v) => v.to_str().unwrap_or_default().to_string(),
None => remote_address.to_string(),
};
let user_agent = headers
.get(axum::http::header::USER_AGENT)
.map(|v| v.to_str().unwrap_or_default())
.unwrap_or_default()
.to_string();
(ip, user_agent)
}
pub fn get_url_from_host(host: &str) -> String {
let port: Option<u16> = 'p: {
let split_port: Vec<&str> = host.split(':').collect();
if split_port.len() == 2 {
if let Ok(p) = split_port[1].parse::<u16>() {
break 'p Some(p);
}
}
None
};
format!(
"http{}://{}",
if port.is_some() && port.unwrap() != 443 {
""
} else {
"s"
},
host
)
}
pub fn substitute(str: &str, pattern: &str, replacements: &[&str]) -> String {
let mut result = String::with_capacity(
(str.len() + replacements.iter().map(|s| s.len()).sum::<usize>())
.saturating_sub(pattern.len() * replacements.len()),
);
let mut i = 0;
for s in str.split(pattern) {
result.push_str(s);
if i < replacements.len() {
result.push_str(replacements[i]);
}
i += 1;
}
if i == 1 {
return str.to_string();
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_substitute() {
assert_eq!(substitute("", "", &[]), "");
assert_eq!(substitute("", "", &[""]), "");
assert_eq!(substitute("", "{}", &["a"]), "");
assert_eq!(substitute("a", "{}", &["b"]), "a");
assert_eq!(substitute("a{}", "{}", &["b"]), "ab");
assert_eq!(substitute("{}c", "{}", &["b"]), "bc");
assert_eq!(substitute("a{}c", "{}", &["b"]), "abc");
assert_eq!(substitute("{}b{}", "{}", &["a", "c"]), "abc");
assert_eq!(substitute("{}{}{}", "{}", &["a", "bc", "def"]), "abcdef");
assert_eq!(substitute("{}{}{}", "{}", &["a"]), "a");
}
}