oi_pkg_checker_core/packages/
de_serialization.rs

1use std::{
2    fmt::Display,
3    fs::File,
4    io::{Read, Write},
5    path::Path,
6};
7
8use bincode::{deserialize, serialize};
9use fmri::FMRI;
10use serde::{Deserialize, Serialize};
11
12use crate::{
13    clone, downgrade, get, get_mut, new,
14    packages::{
15        package::{Package as OrgPackage, PackageVersion},
16        rev_depend_type::RevDependType,
17    },
18    shared_type, weak_type, Component as OrgComponent, Components as OrgComponents, Problems,
19};
20
21#[derive(Serialize, Deserialize)]
22pub struct Components {
23    components: Vec<Component>,
24    packages: Vec<Package>,
25    problems: Problems,
26}
27#[derive(Serialize, Deserialize)]
28pub struct Component {
29    name: String,
30    packages: Vec<FMRI>,
31    build: Vec<FMRI>,
32    test: Vec<FMRI>,
33    sys_build: Vec<FMRI>,
34    sys_test: Vec<FMRI>,
35}
36#[derive(Serialize, Deserialize)]
37pub struct Package {
38    fmri: FMRI,
39    versions: Vec<PackageVersion>,
40    component: Option<String>,
41    obsolete: bool,
42    renamed: bool,
43    runtime_dependents: Vec<RevDependType>,
44    build_dependents: Vec<String>,
45    test_dependents: Vec<String>,
46    sys_build_dependents: Vec<String>,
47    sys_test_dependents: Vec<String>,
48}
49
50impl OrgComponents {
51    pub fn deserialize<P: AsRef<Path> + ?Sized + Display>(path: &P) -> Result<Self, String> {
52        let data = &mut Vec::new();
53        File::open(path)
54            .map_err(|e| format!("failed to open file {}: {}", path, e))?
55            .read_to_end(data)
56            .map_err(|e| format!("failed to read file: {}", e))?;
57        let components: Components =
58            deserialize(data).map_err(|e| format!("failed to deserialize data: {}", e))?;
59
60        let mut org_components = OrgComponents {
61            problems: components.problems,
62            ..Default::default()
63        };
64
65        for package in &components.packages {
66            let p = new!(OrgPackage {
67                fmri: package.fmri.clone(),
68                versions: package.versions.clone(),
69                component: None,
70                obsolete: package.obsolete,
71                renamed: package.renamed,
72                runtime_dependents: package.runtime_dependents.clone(),
73                build_dependents: Vec::new(),
74                test_dependents: Vec::new(),
75                sys_build_dependents: Vec::new(),
76                sys_test_dependents: Vec::new(),
77            });
78
79            org_components.packages.push(clone!(&p));
80            org_components.hash_packages.insert(
81                package.fmri.clone().get_package_name_as_string(),
82                clone!(&p),
83            );
84        }
85
86        for component in components.components {
87            let c = |v: Vec<FMRI>| -> Vec<weak_type!(OrgPackage)> {
88                v.iter()
89                    .map(|f| downgrade!(org_components.get_package_by_fmri(f).unwrap()))
90                    .collect()
91            };
92            let a = new!(OrgComponent {
93                name: component.name.clone(),
94                packages: c(component.packages),
95                build: c(component.build),
96                test: c(component.test),
97                sys_build: c(component.sys_build),
98                sys_test: c(component.sys_test),
99            });
100
101            org_components.components.push(clone!(&a));
102            org_components
103                .hash_components
104                .insert(component.name, clone!(&a));
105        }
106
107        for p in &components.packages {
108            let mut package = get_mut!(org_components.get_package_by_fmri(&p.fmri).unwrap());
109
110            package.component = p
111                .component
112                .as_ref()
113                .map(|name| clone!(org_components.get_component_by_name(name).unwrap()));
114
115            let c = |cs: Vec<String>| -> Vec<shared_type!(OrgComponent)> {
116                cs.iter()
117                    .map(|name| clone!(org_components.get_component_by_name(name).unwrap()))
118                    .collect()
119            };
120
121            package.build_dependents = c(p.build_dependents.clone());
122            package.test_dependents = c(p.test_dependents.clone());
123            package.sys_build_dependents = c(p.sys_build_dependents.clone());
124            package.sys_test_dependents = c(p.sys_test_dependents.clone());
125        }
126
127        Ok(org_components)
128    }
129
130    pub fn serialize<P: AsRef<Path> + ?Sized + Display>(&self, path: &P) -> Result<(), String> {
131        let mut components = Components {
132            packages: Vec::new(),
133            components: Vec::new(),
134            problems: self.problems.clone(),
135        };
136
137        let cn = |c: shared_type!(OrgComponent)| -> String { get!(c).get_name().clone() };
138        let cnr = |c: &shared_type!(OrgComponent)| -> String { get!(c).get_name().clone() };
139        let f = |p: &weak_type!(OrgPackage)| -> FMRI { get!(p.upgrade().unwrap()).fmri.clone() };
140
141        for p in &self.packages {
142            let package = get!(p);
143            components.packages.push(Package {
144                fmri: package.fmri.clone(),
145                versions: package.versions.clone(),
146                component: package.component.clone().map(cn),
147                obsolete: package.is_obsolete(),
148                renamed: package.is_renamed(),
149                runtime_dependents: package.runtime_dependents.clone(),
150                build_dependents: package.build_dependents.iter().map(cnr).collect(),
151                test_dependents: package.test_dependents.iter().map(cnr).collect(),
152                sys_build_dependents: package.sys_build_dependents.iter().map(cnr).collect(),
153                sys_test_dependents: package.sys_test_dependents.iter().map(cnr).collect(),
154            });
155        }
156
157        for c in &self.components {
158            let component = get!(c);
159            components.components.push(Component {
160                name: component.get_name().clone(),
161                packages: component.packages.iter().map(f).collect(),
162                build: component.build.iter().map(f).collect(),
163                test: component.test.iter().map(f).collect(),
164                sys_build: component.sys_build.iter().map(f).collect(),
165                sys_test: component.sys_test.iter().map(f).collect(),
166            });
167        }
168
169        File::create(path)
170            .map_err(|e| format!("failed to create file {}: {}", path, e))?
171            .write_all(
172                &serialize(&components)
173                    .map_err(|e| format!("failed to serialize components: {}", e))?,
174            )
175            .map_err(|e| format!("failed to write serialized data into file: {}", e))?;
176        Ok(())
177    }
178}