oi_pkg_checker_core/packages/
de_serialization.rs1use 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}