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