gitcp/
source.rs

1use crate::error::Error;
2
3#[derive(Debug)]
4pub struct Source {
5    pub download_url: String,
6    pub glob_pattern: String,
7}
8
9impl Source {
10    pub fn parse(raw: impl Into<String>) -> crate::result::Result<Self> {
11        let raw = raw.into();
12        let mut sections = raw.split('@');
13        let body = sections.next().unwrap();
14        let reference = sections.next();
15
16        let mut parts = body.splitn(3, '/');
17
18        let owner = parts.next().unwrap();
19        let name = parts.next().ok_or(Error::InvalidSourceError {
20            source: owner.to_string(),
21        })?;
22        let file_path = parts.next();
23
24        let download_url = format!(
25            "https://api.github.com/repos/{owner}/{name}/tarball/{reference}",
26            name = name,
27            owner = owner,
28            reference = reference.unwrap_or(""),
29        );
30
31        let glob_pattern = format!("*/{}", file_path.unwrap_or("*"));
32
33        Ok(Source {
34            download_url,
35            glob_pattern,
36        })
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    #[test]
43    fn test_parse() {
44        let raw = "rust-lang/rust";
45        let source = super::Source::parse(raw).unwrap();
46        assert_eq!(
47            "https://api.github.com/repos/rust-lang/rust/tarball/",
48            source.download_url
49        );
50        assert_eq!("*/*", source.glob_pattern);
51    }
52
53    #[test]
54    fn test_parse_with_file_path() {
55        let raw = "rust-lang/rust/README.md";
56        let source = super::Source::parse(raw).unwrap();
57        assert_eq!(
58            "https://api.github.com/repos/rust-lang/rust/tarball/",
59            source.download_url
60        );
61        assert_eq!("*/README.md", source.glob_pattern);
62    }
63
64    #[test]
65    fn test_parse_with_reference() {
66        let raw = "rust-lang/rust@main";
67        let source = super::Source::parse(raw).unwrap();
68        assert_eq!(
69            "https://api.github.com/repos/rust-lang/rust/tarball/main",
70            source.download_url
71        );
72        assert_eq!("*/*", source.glob_pattern);
73    }
74
75    #[test]
76    fn test_parse_with_file_path_and_reference() {
77        let raw = "rust-lang/rust/README.md@main";
78        let source = super::Source::parse(raw).unwrap();
79        assert_eq!(
80            "https://api.github.com/repos/rust-lang/rust/tarball/main",
81            source.download_url
82        );
83        assert_eq!("*/README.md", source.glob_pattern);
84    }
85}