Skip to main content

upstream_rs/models/upstream/
package_reference.rs

1use crate::models::{
2    common::enums::{Channel, Filetype, Provider},
3    upstream::Package,
4};
5use serde::{Deserialize, Serialize};
6
7/// The bare minimum needed to install a package. Essentially the args to
8/// `Package::with_defaults` — no install state, no paths, no version.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct PackageReference {
11    pub name: String,
12    pub repo_slug: String,
13    pub filetype: Filetype,
14    pub channel: Channel,
15    pub provider: Provider,
16    pub base_url: Option<String>,
17    pub build_branch: Option<String>,
18    pub build_commit: Option<String>,
19    pub match_pattern: Option<String>,
20    pub exclude_pattern: Option<String>,
21}
22
23impl PackageReference {
24    pub fn into_package(self) -> Package {
25        let mut package = Package::with_defaults(
26            self.name,
27            self.repo_slug,
28            self.filetype,
29            self.match_pattern,
30            self.exclude_pattern,
31            self.channel,
32            self.provider,
33            self.base_url,
34        );
35        package.build_branch = self.build_branch;
36        package.build_commit = self.build_commit;
37        package
38    }
39
40    pub fn from_package(package: Package) -> Self {
41        Self {
42            name: package.name,
43            repo_slug: package.repo_slug,
44            filetype: package.filetype,
45            channel: package.channel,
46            provider: package.provider,
47            base_url: package.base_url,
48            build_branch: package.build_branch,
49            build_commit: package.build_commit,
50            match_pattern: package.match_pattern,
51            exclude_pattern: package.exclude_pattern,
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::PackageReference;
59    use crate::models::common::enums::{Channel, Filetype, Provider};
60    use crate::models::upstream::Package;
61
62    fn reference() -> PackageReference {
63        PackageReference {
64            name: "fd".to_string(),
65            repo_slug: "sharkdp/fd".to_string(),
66            filetype: Filetype::Archive,
67            channel: Channel::Stable,
68            provider: Provider::Github,
69            base_url: Some("https://api.github.com".to_string()),
70            build_branch: Some("main".to_string()),
71            build_commit: Some("abcdef123456".to_string()),
72            match_pattern: Some("x86_64".to_string()),
73            exclude_pattern: Some("debug".to_string()),
74        }
75    }
76
77    #[test]
78    fn into_package_keeps_install_inputs_and_applies_runtime_defaults() {
79        let package = reference().into_package();
80
81        assert_eq!(package.name, "fd");
82        assert_eq!(package.repo_slug, "sharkdp/fd");
83        assert_eq!(package.filetype, Filetype::Archive);
84        assert_eq!(package.channel, Channel::Stable);
85        assert_eq!(package.provider, Provider::Github);
86        assert_eq!(package.base_url.as_deref(), Some("https://api.github.com"));
87        assert_eq!(package.build_branch.as_deref(), Some("main"));
88        assert_eq!(package.build_commit.as_deref(), Some("abcdef123456"));
89        assert!(package.install_path.is_none());
90        assert!(package.exec_path.is_none());
91        assert_eq!(package.version.to_string(), "0.0.0");
92    }
93
94    #[test]
95    fn from_package_round_trips_reference_fields() {
96        let mut package = Package::with_defaults(
97            "ripgrep".to_string(),
98            "BurntSushi/ripgrep".to_string(),
99            Filetype::Binary,
100            Some("linux".to_string()),
101            Some("symbols".to_string()),
102            Channel::Preview,
103            Provider::Github,
104            None,
105        );
106        package.build_branch = Some("dev".to_string());
107        package.build_commit = Some("0123456789abcdef".to_string());
108
109        let reference = PackageReference::from_package(package);
110        assert_eq!(reference.name, "ripgrep");
111        assert_eq!(reference.repo_slug, "BurntSushi/ripgrep");
112        assert_eq!(reference.filetype, Filetype::Binary);
113        assert_eq!(reference.channel, Channel::Preview);
114        assert_eq!(reference.provider, Provider::Github);
115        assert_eq!(reference.build_branch.as_deref(), Some("dev"));
116        assert_eq!(reference.build_commit.as_deref(), Some("0123456789abcdef"));
117        assert_eq!(reference.match_pattern.as_deref(), Some("linux"));
118        assert_eq!(reference.exclude_pattern.as_deref(), Some("symbols"));
119    }
120}