Skip to main content

setzer_import/
assets.rs

1//! Asset ids, shared by both importers.
2
3use setzer_model::asset::Asset;
4
5/// Largest image we import.
6pub const MAX_IMAGE_BYTES: u64 = 100 * 1024 * 1024;
7
8/// File name for an image's asset: the original base name (`/` or `\`
9/// paths), sanitized, with the extension that matches the content, made
10/// unique among `assets`.
11pub fn unique_id(path: &str, ext: &str, assets: &[Asset]) -> String {
12    let base = path.rsplit(['/', '\\']).next().unwrap_or("image");
13    let stem = base.rsplit_once('.').map_or(base, |(s, _)| s);
14    let clean: String = stem
15        .chars()
16        .map(|c| {
17            if c.is_ascii_alphanumeric() || c == '-' || c == '_' {
18                c
19            } else {
20                '_'
21            }
22        })
23        .collect();
24    let clean = if clean.is_empty() {
25        "image".into()
26    } else {
27        clean
28    };
29    let mut id = format!("{clean}.{ext}");
30    let mut n = 2;
31    while assets.iter().any(|a| a.id == id) {
32        id = format!("{clean}-{n}.{ext}");
33        n += 1;
34    }
35    id
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn ids_are_sanitized_and_unique() {
44        let taken = vec![Asset::new("map.png", Vec::new())];
45        assert_eq!(unique_id("img/Karte 1.jpeg", "jpg", &[]), "Karte_1.jpg");
46        assert_eq!(unique_id(r"bilder\map.PNG", "png", &taken), "map-2.png");
47        assert_eq!(unique_id(".png", "png", &[]), "image.png");
48        assert!(Asset::is_valid_id(&unique_id("ü/ö ä", "gif", &[])));
49    }
50}