flatpak_rs/
reverse_dns.rs

1use lazy_static::lazy_static;
2use regex::Regex;
3
4lazy_static! {
5    static ref REVERSE_DNS_FILENAME_REGEX: Regex = Regex::new(
6        r"[a-z][a-z][a-z]*\.[a-z][0-9a-zA-Z_\-]+\.[a-z][0-9a-zA-Z_\-]+(\.[a-z][0-9a-zA-Z_\-]+)*\.(json|yaml|yml)$"
7    ).unwrap();
8}
9
10pub fn is_reverse_dns(path: &str) -> bool {
11    let path = path.to_lowercase();
12    REVERSE_DNS_FILENAME_REGEX.is_match(&path)
13}
14
15/// Transforms a URL into its reverse DNS equivalent.
16///```
17///let mut reverse_dns = flatpak_rs::reverse_dns::from_url("https://github.com/louib/flatpak-rs.git");
18///assert_eq!(reverse_dns, "com.github.louib.flatpak-rs");
19///reverse_dns =
20///flatpak_rs::reverse_dns::from_url("https://gitlab.com/louib/flatpak-rs.git");
21///assert_eq!(reverse_dns, "com.gitlab.louib.flatpak-rs");
22///reverse_dns = flatpak_rs::reverse_dns::from_url("https://git.savannah.gnu.org/cgit/make.git");
23///assert_eq!(reverse_dns, "org.gnu.savannah.git.cgit.make");
24///reverse_dns = flatpak_rs::reverse_dns::from_url("https://gitlab.freedesktop.org/xorg/lib/libxmu");
25///assert_eq!(reverse_dns, "org.freedesktop.gitlab.xorg.lib.libxmu");
26///```
27pub fn from_url(url: &str) -> String {
28    if !url.starts_with("https://") {
29        panic!("Only supports https urls: {}", url);
30    }
31    let mut sanitized_url = url[8..].to_string();
32
33    if url.ends_with(".git") {
34        // Removing the .git at the end of the url.
35        // There has to be a better way to do this...
36        // But rust has no negative index for the list
37        // comprehension.
38        sanitized_url.pop();
39        sanitized_url.pop();
40        sanitized_url.pop();
41        sanitized_url.pop();
42    }
43
44    let mut repo_url_parts = sanitized_url.split("/");
45    let domain = repo_url_parts.next().unwrap();
46    let mut reversed_domain: String = "".to_string();
47
48    let domain_parts = domain.split(".");
49    for domain_part in domain_parts {
50        if reversed_domain.len() == 0 {
51            reversed_domain = domain_part.to_string();
52        } else {
53            reversed_domain = format!("{}.{}", domain_part, reversed_domain);
54        }
55    }
56
57    let mut next_url_part = repo_url_parts.next();
58    while next_url_part.is_some() {
59        reversed_domain += ".";
60        reversed_domain += next_url_part.unwrap();
61        next_url_part = repo_url_parts.next();
62    }
63    reversed_domain
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    pub fn test_file_path_matches() {
72        assert!(is_reverse_dns("com.example.appName.yaml"));
73        assert!(is_reverse_dns("COM.EXAMPLE.APPNAME.YAML"));
74        assert!(is_reverse_dns("io.github.user.repo.Devel.yaml"));
75        assert!(is_reverse_dns("/path/to/com.example.appName.yaml"));
76        assert!(is_reverse_dns("/path/to/com.example.appName.yml"));
77        assert!(is_reverse_dns("/path/to/com.example.department.product.yaml"));
78        assert!(is_reverse_dns(
79            "/path/to/com.example.department.name-of-product.yaml"
80        ));
81        assert!(is_reverse_dns("contrib/linux/com.dosbox_x.DOSBox-X.yaml"));
82        assert!(!is_reverse_dns(
83            "/tmp/com.github.flathub.org.freedesktop.LinuxAudio.Plugins.WolfShaper/flathub.json"
84        ));
85        assert!(!is_reverse_dns("Firefox-62.0.3.update.json"));
86        assert!(!is_reverse_dns("/path/to/file.yaml"));
87        assert!(!is_reverse_dns("/path/to/file.json"));
88        assert!(!is_reverse_dns("/path/to/___432423fdsf.json"));
89        assert!(!is_reverse_dns("/path/to/example.com.json"));
90        assert!(!is_reverse_dns("/path/to/example.com.json."));
91        assert!(!is_reverse_dns(""));
92        assert!(!is_reverse_dns("/////////////"));
93    }
94}