use super::Sizing;
pub(super) use crate::path_ext::path_extension_lower;
#[allow(dead_code)]
pub(super) fn build_src(path: &str, query: Option<&str>, fragment: Option<&str>) -> String {
let mut out = String::from(path);
if let Some(q) = query {
out.push('?');
out.push_str(q);
}
if let Some(f) = fragment {
out.push('#');
out.push_str(f);
}
out
}
#[allow(dead_code)]
pub(super) fn dim_attrs(alias: Option<&str>) -> (String, String) {
let Some(a) = alias else {
return (String::new(), String::new());
};
match Sizing::parse(a) {
Some(Sizing::Width(w)) => (format!(" width=\"{}\"", w.to_css()), String::new()),
Some(Sizing::Box(w, h)) => (
format!(" width=\"{}\"", w.to_css()),
format!(" height=\"{}\"", h.to_css()),
),
None => (String::new(), String::new()),
}
}
pub fn html_escape_attr(s: &str) -> String {
s.replace('&', "&")
.replace('<', "<")
.replace('>', ">")
.replace('"', """)
}
#[allow(dead_code)]
pub(super) fn width_attr(width: Option<&str>) -> String {
match width {
Some(w) => format!(r#" data-width="{}""#, html_escape_attr(w)),
None => String::new(),
}
}
pub fn file_stem(path: &str) -> String {
let filename = path.rsplit('/').next().unwrap_or(path);
match filename.rsplit_once('.') {
Some((stem, _ext)) if !stem.is_empty() => stem.to_string(),
_ => filename.to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_build_src_plain() {
assert_eq!(build_src("file.html", None, None), "file.html");
}
#[test]
fn test_build_src_with_query() {
assert_eq!(
build_src("file.html", Some("x=1&y=2"), None),
"file.html?x=1&y=2"
);
}
#[test]
fn test_build_src_with_query_and_fragment() {
assert_eq!(
build_src("doc.html", Some("x=1"), Some("sec")),
"doc.html?x=1#sec"
);
}
#[test]
fn test_html_escape_attr() {
assert_eq!(html_escape_attr("a&b"), "a&b");
assert_eq!(html_escape_attr("a<b>c"), "a<b>c");
assert_eq!(html_escape_attr("say \"hi\""), "say "hi"");
}
#[test]
fn test_html_escape_attr_apostrophe_passthrough() {
assert_eq!(html_escape_attr("it's"), "it's");
assert_eq!(html_escape_attr("path/it's-here.mp3"), "path/it's-here.mp3");
}
#[test]
fn test_file_stem() {
assert_eq!(file_stem("photo.jpg"), "photo");
assert_eq!(file_stem("dir/photo.jpg"), "photo");
assert_eq!(file_stem("noext"), "noext");
assert_eq!(file_stem(".dotfile"), ".dotfile");
}
#[test]
fn test_path_extension_lower() {
assert_eq!(path_extension_lower("photo.JPG"), "jpg");
assert_eq!(path_extension_lower("dir/file.mp4"), "mp4");
assert_eq!(path_extension_lower("noext"), "");
}
#[test]
fn test_dim_attrs_none() {
assert_eq!(dim_attrs(None), (String::new(), String::new()));
}
#[test]
fn test_dim_attrs_width_only() {
let (w, h) = dim_attrs(Some("400"));
assert_eq!(w, " width=\"400px\"");
assert_eq!(h, "");
}
#[test]
fn test_dim_attrs_box() {
let (w, h) = dim_attrs(Some("100%x600"));
assert_eq!(w, " width=\"100%\"");
assert_eq!(h, " height=\"600px\"");
}
}