oi_pkg_checker_core/packages/
package.rs

1use std::cmp::Ordering;
2
3use fmri::{FMRI, Version};
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    Component,
8    DependTypes,
9    get,
10    packages::{
11        dependency_type::{
12            DependencyTypes,
13            DependencyTypes::{Build, Runtime, SystemBuild, SystemTest, Test},
14        },
15        rev_depend_type::RevDependType,
16    }, problems::{Problem, Problem::PackageInMultipleComponents}, shared_type,
17};
18
19/// Package. Can hold multiple versions with different runtime dependencies.
20#[derive(Clone, Debug)]
21pub struct Package {
22    /// contains no version
23    pub(crate) fmri: FMRI,
24    /// versions of package
25    pub(crate) versions: Vec<PackageVersion>,
26    /// reference to component, if package is in component
27    pub(crate) component: Option<shared_type!(Component)>,
28    pub(crate) obsolete: bool,
29    pub(crate) renamed: bool,
30    /// packages that depend on this package
31    pub(crate) runtime_dependents: Vec<RevDependType>,
32    pub(crate) build_dependents: Vec<shared_type!(Component)>,
33    pub(crate) test_dependents: Vec<shared_type!(Component)>,
34    pub(crate) sys_build_dependents: Vec<shared_type!(Component)>,
35    pub(crate) sys_test_dependents: Vec<shared_type!(Component)>,
36}
37
38impl Package {
39    /// for creating new empty package
40    pub fn new(fmri: FMRI) -> Self {
41        Self {
42            fmri,
43            versions: Vec::new(),
44            component: None,
45            runtime_dependents: Vec::new(),
46            obsolete: false,
47            renamed: false,
48            build_dependents: Vec::new(),
49            test_dependents: Vec::new(),
50            sys_build_dependents: Vec::new(),
51            sys_test_dependents: Vec::new(),
52        }
53    }
54
55    pub fn add_package_version(&mut self, package_version: PackageVersion) -> Result<(), String> {
56        if self.versions.contains(&package_version) {
57            return Ok(());
58        }
59
60        for ver in &self.versions {
61            if ver.version.cmp(&package_version.version) == Ordering::Equal {
62                return Ok(());
63            }
64        }
65
66        if package_version.is_obsolete() && package_version.is_renamed() {
67            return Err(format!(
68                "package cannot be obsolete and renamed at the same time, package: {:?}",
69                package_version
70            ));
71        }
72
73        self.set_obsolete(package_version.is_obsolete());
74        self.set_renamed(package_version.is_renamed());
75
76        self.versions.push(package_version);
77        Ok(())
78    }
79
80    pub fn add_dependent(
81        &mut self,
82        dependent: shared_type!(Component),
83        dependency_type: &DependencyTypes,
84    ) -> Result<(), String> {
85        match dependency_type {
86            Runtime => return Err("you can not add runtime dependent".to_owned()),
87            Build => self.build_dependents.push(dependent),
88            Test => self.test_dependents.push(dependent),
89            SystemBuild => self.sys_build_dependents.push(dependent),
90            SystemTest => self.sys_test_dependents.push(dependent),
91        }
92        Ok(())
93    }
94
95    pub fn set_component(&mut self, component: shared_type!(Component)) -> Option<Box<Problem>> {
96        if let Some(c) = &self.component {
97            return Some(Box::new(PackageInMultipleComponents(
98                self.fmri.clone(),
99                vec![
100                    get!(c).get_name().to_owned(),
101                    get!(component).get_name().to_owned(),
102                ],
103            )));
104        } else {
105            self.component = Some(component)
106        }
107        None
108    }
109
110    pub fn get_versions(&self) -> &Vec<PackageVersion> {
111        &self.versions
112    }
113
114    pub fn get_versions_mut(&mut self) -> &mut Vec<PackageVersion> {
115        &mut self.versions
116    }
117
118    pub fn set_obsolete(&mut self, obsolete: bool) {
119        self.obsolete = obsolete
120    }
121
122    pub fn set_renamed(&mut self, renamed: bool) {
123        self.renamed = renamed
124    }
125
126    pub fn is_obsolete(&self) -> bool {
127        self.obsolete
128    }
129
130    pub fn is_renamed(&self) -> bool {
131        self.renamed
132    }
133
134    pub fn is_in_component(&self) -> &Option<shared_type!(Component)> {
135        &self.component
136    }
137
138    pub fn get_runtime_dependents(&self) -> &Vec<RevDependType> {
139        &self.runtime_dependents
140    }
141
142    pub fn get_git_dependents(
143        &self,
144        dependency_type: DependencyTypes,
145    ) -> Result<&Vec<shared_type!(Component)>, String> {
146        Ok(match dependency_type {
147            Runtime => return Err("you can not add runtime dependent".to_owned()),
148            Build => &self.build_dependents,
149            Test => &self.test_dependents,
150            SystemBuild => &self.sys_build_dependents,
151            SystemTest => &self.sys_test_dependents,
152        })
153    }
154
155    pub fn change_versions(&mut self, vers: Vec<PackageVersion>) {
156        self.versions = vers
157    }
158
159    pub fn get_fmri(&self) -> &FMRI {
160        &self.fmri
161    }
162}
163
164/// PackageVersion represents one version of package
165#[derive(Serialize, Deserialize, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
166pub struct PackageVersion {
167    /// package version
168    pub(crate) version: Version,
169    /// runtime dependencies
170    pub(crate) runtime: Vec<DependTypes>,
171    obsolete: bool,
172    renamed: bool,
173}
174
175impl PackageVersion {
176    /// for creating new empty version of package
177    pub fn new(version: Version) -> Self {
178        Self {
179            version,
180            runtime: vec![],
181            obsolete: false,
182            renamed: false,
183        }
184    }
185
186    pub fn add_runtime_dependencies(&mut self, runtime: &mut Vec<DependTypes>) -> &Self {
187        self.runtime.append(runtime);
188        self
189    }
190
191    pub fn get_runtime_dependencies(&self) -> &Vec<DependTypes> {
192        &self.runtime
193    }
194
195    pub fn set_obsolete(&mut self, obsolete: bool) -> &Self {
196        self.obsolete = obsolete;
197        self
198    }
199
200    pub fn set_renamed(&mut self, renamed: bool) -> &Self {
201        self.renamed = renamed;
202        self
203    }
204
205    pub fn is_obsolete(&self) -> bool {
206        self.obsolete
207    }
208
209    pub fn is_renamed(&self) -> bool {
210        self.renamed
211    }
212}