junobuild_storage/
rewrites.rs

1use crate::constants::ROOT_PATHS;
2use crate::types::config::{StorageConfig, StorageConfigRedirect};
3use crate::url::{matching_urls as matching_urls_utils, separator};
4use std::cmp::Ordering;
5use std::collections::HashMap;
6
7pub fn rewrite_url(requested_path: &str, config: &StorageConfig) -> Option<(String, String)> {
8    let StorageConfig { rewrites, .. } = config;
9
10    let matches = matching_urls(requested_path, rewrites);
11
12    matches
13        .first()
14        .map(|(source, destination)| (rewrite_source_to_path(source).clone(), destination.clone()))
15}
16
17pub fn rewrite_source_to_path(source: &str) -> String {
18    [separator(source), source].join("").replace('*', "")
19}
20
21pub fn is_root_path(path: &str) -> bool {
22    ROOT_PATHS.contains(&path)
23}
24
25pub fn redirect_url(requested_path: &str, config: &StorageConfig) -> Option<StorageConfigRedirect> {
26    let redirects = config.unwrap_redirects();
27
28    let matches = matching_urls(requested_path, &redirects);
29
30    matches.first().map(|(_, redirect)| redirect.clone())
31}
32
33fn matching_urls<T: Clone>(requested_path: &str, config: &HashMap<String, T>) -> Vec<(String, T)> {
34    let mut matches: Vec<(String, T)> = matching_urls_utils(requested_path, config);
35
36    matches.sort_by(|(a, _), (b, _)| {
37        let a_parts: Vec<&str> = a.split('/').collect();
38        let b_parts: Vec<&str> = b.split('/').collect();
39
40        // Compare the lengths first (in reverse order for longer length first - i.e. the rewrite with the more sub-paths first)
41        let length_cmp = b_parts.len().cmp(&a_parts.len());
42
43        if length_cmp == Ordering::Equal {
44            // If lengths are equal, sort alphabetically
45            a.cmp(b)
46        } else {
47            length_cmp
48        }
49    });
50
51    matches
52}