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}