Skip to main content

rust_fontconfig/
utils.rs

1use alloc::string::String;
2
3/// Known font file extensions (lowercase).
4pub const FONT_EXTENSIONS: &[&str] = &["ttf", "otf", "ttc", "woff", "woff2", "dfont"];
5
6/// Normalize a family/font name for comparison: lowercase, strip all non-alphanumeric characters.
7///
8/// This ensures consistent matching regardless of spaces, hyphens, underscores, or casing.
9pub fn normalize_family_name(name: &str) -> String {
10    name.chars()
11        .filter(|c| c.is_alphanumeric())
12        .map(|c| c.to_ascii_lowercase())
13        .collect()
14}
15
16/// Check if a file has a recognized font extension.
17#[cfg(feature = "std")]
18pub fn is_font_file(path: &std::path::Path) -> bool {
19    path.extension()
20        .and_then(|e| e.to_str())
21        .map(|ext| {
22            let lower = ext.to_lowercase();
23            FONT_EXTENSIONS.contains(&lower.as_str())
24        })
25        .unwrap_or(false)
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn font_extensions_covers_common_formats() {
34        for ext in &["ttf", "otf", "ttc", "woff", "woff2"] {
35            assert!(FONT_EXTENSIONS.contains(ext), "missing extension: {}", ext);
36        }
37    }
38
39    #[cfg(feature = "std")]
40    #[test]
41    fn is_font_file_recognizes_fonts() {
42        use std::path::Path;
43        assert!(is_font_file(Path::new("Arial.ttf")));
44        assert!(is_font_file(Path::new("NotoSans.otf")));
45        assert!(is_font_file(Path::new("Font.TTC"))); // case insensitive
46        assert!(is_font_file(Path::new("web.woff2")));
47    }
48
49    #[cfg(feature = "std")]
50    #[test]
51    fn is_font_file_rejects_non_fonts() {
52        use std::path::Path;
53        assert!(!is_font_file(Path::new("readme.txt")));
54        assert!(!is_font_file(Path::new("image.png")));
55        assert!(!is_font_file(Path::new("no_extension")));
56    }
57}