upstream_rs/models/upstream/
package.rs1use std::path::PathBuf;
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::models::common::{
7 enums::{Channel, Filetype, Provider},
8 version::Version,
9};
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct Package {
13 pub name: String,
14 pub repo_slug: String,
15
16 pub filetype: Filetype,
17 pub version: Version,
18 pub channel: Channel,
19 pub provider: Provider,
20 pub base_url: Option<String>,
21
22 pub is_pinned: bool,
23 pub match_pattern: Option<String>,
24 pub exclude_pattern: Option<String>,
25 pub icon_path: Option<PathBuf>,
26 pub install_path: Option<PathBuf>,
27 pub exec_path: Option<PathBuf>,
28
29 pub last_upgraded: DateTime<Utc>,
30}
31
32impl Package {
33 #[allow(clippy::too_many_arguments)]
34 pub fn with_defaults(
35 name: String,
36 repo_slug: String,
37 filetype: Filetype,
38 match_pattern: Option<String>,
39 exclude_pattern: Option<String>,
40 channel: Channel,
41 provider: Provider,
42 base_url: Option<String>,
43 ) -> Self {
44 Self {
45 name,
46 repo_slug,
47
48 filetype,
49 version: Version::new(0, 0, 0, false),
50 channel,
51 provider,
52 base_url,
53
54 is_pinned: false,
55 match_pattern,
56 exclude_pattern,
57 icon_path: None,
58 install_path: None,
59 exec_path: None,
60
61 last_upgraded: Utc::now(),
62 }
63 }
64
65 pub fn is_same_as(&self, other: &Package) -> bool {
66 self.provider == other.provider
67 && self.repo_slug == other.repo_slug
68 && self.channel == other.channel
69 && self.name == other.name
70 && self.base_url == other.base_url
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::Package;
77 use crate::models::common::enums::{Channel, Filetype, Provider};
78
79 #[test]
80 fn with_defaults_sets_expected_base_state() {
81 let pkg = Package::with_defaults(
82 "bat".to_string(),
83 "sharkdp/bat".to_string(),
84 Filetype::Auto,
85 Some("linux".to_string()),
86 Some("debug".to_string()),
87 Channel::Stable,
88 Provider::Github,
89 None,
90 );
91
92 assert_eq!(pkg.version.major, 0);
93 assert!(!pkg.is_pinned);
94 assert!(pkg.install_path.is_none());
95 assert!(pkg.exec_path.is_none());
96 assert_eq!(pkg.match_pattern.as_deref(), Some("linux"));
97 assert_eq!(pkg.exclude_pattern.as_deref(), Some("debug"));
98 }
99
100 #[test]
101 fn is_same_as_uses_identity_fields_only() {
102 let mut a = Package::with_defaults(
103 "ripgrep".to_string(),
104 "BurntSushi/ripgrep".to_string(),
105 Filetype::Archive,
106 None,
107 None,
108 Channel::Stable,
109 Provider::Github,
110 Some("https://api.github.com".to_string()),
111 );
112 let mut b = a.clone();
113 b.version.major = 99;
114 b.is_pinned = true;
115 b.match_pattern = Some("x86_64".to_string());
116 assert!(a.is_same_as(&b));
117
118 a.name = "rg".to_string();
119 assert!(!a.is_same_as(&b));
120 }
121}