1use std::cell::{Ref, RefCell};
4
5use cxx::UniquePtr;
6
7#[allow(non_upper_case_globals, non_snake_case)]
28pub mod RecordField {
29 pub const Package: &str = "Package";
31
32 pub const Source: &str = "Source";
37
38 pub const Version: &str = "Version";
40
41 pub const InstalledSize: &str = "Installed-Size";
43
44 pub const Homepage: &str = "Homepage";
47
48 pub const Essential: &str = "Essential";
50
51 pub const Maintainer: &str = "Maintainer";
54
55 pub const OriginalMaintainer: &str = "Original-Maintainer";
59
60 pub const Architecture: &str = "Architecture";
62
63 pub const Replaces: &str = "Replaces";
66
67 pub const Provides: &str = "Provides";
70
71 pub const PreDepends: &str = "Pre-Depends";
74
75 pub const Depends: &str = "Depends";
78
79 pub const Recommends: &str = "Recommends";
82
83 pub const Suggests: &str = "Suggests";
86
87 pub const Breaks: &str = "Breaks";
90
91 pub const Conflicts: &str = "Conflicts";
94
95 pub const Description: &str = "Description";
98
99 pub const DescriptionMD5: &str = "Description-md5";
102
103 pub const Tag: &str = "Tag";
106
107 pub const MultiArch: &str = "Multi-Arch";
110
111 pub const Section: &str = "Section";
113
114 pub const Priority: &str = "Priority";
116
117 pub const Filename: &str = "Filename";
120
121 pub const Size: &str = "Size";
123
124 pub const MD5sum: &str = "MD5sum";
126
127 pub const SHA256: &str = "SHA256";
130}
131
132pub struct PackageRecords {
133 pub(crate) ptr: UniquePtr<raw::PkgRecords>,
134 parser: RefCell<UniquePtr<raw::Parser>>,
135 index: RefCell<u64>,
136}
137
138impl PackageRecords {
139 pub fn new(ptr: UniquePtr<raw::PkgRecords>) -> PackageRecords {
140 PackageRecords {
141 ptr,
142 parser: RefCell::new(UniquePtr::null()),
143 index: RefCell::new(0),
144 }
145 }
146
147 fn replace_index(&self, index: u64) -> bool {
148 if self.index.borrow().eq(&index) {
149 return false;
150 }
151 self.index.replace(index);
152 true
153 }
154
155 fn parser(&self) -> Ref<'_, UniquePtr<raw::Parser>> {
156 if self.parser.borrow().is_null() {
157 panic!("You must call ver_lookup or desc_lookup first!")
158 }
159 self.parser.borrow()
160 }
161
162 pub fn ver_lookup(&self, file: &raw::VerFileIterator) -> &PackageRecords {
163 if self.replace_index(file.index()) {
164 unsafe { self.parser.replace(self.ptr.ver_lookup(file)) };
165 }
166 self
167 }
168
169 pub fn desc_lookup(&self, file: &raw::DescIterator) -> &PackageRecords {
170 if self.replace_index(file.index()) {
171 unsafe { self.parser.replace(self.ptr.desc_lookup(file)) };
172 }
173 self
174 }
175
176 pub fn short_desc(&self) -> Option<String> { self.parser().short_desc().ok() }
177
178 pub fn long_desc(&self) -> Option<String> { self.parser().long_desc().ok() }
179
180 pub fn filename(&self) -> String { self.parser().filename() }
181
182 pub fn get_field(&self, field: String) -> Option<String> { self.parser().get_field(field).ok() }
183
184 pub fn hash_find(&self, hash_type: String) -> Option<String> {
185 self.parser().hash_find(hash_type).ok()
186 }
187}
188
189type SourceParser<'a> = Ref<'a, UniquePtr<raw::SourceParser>>;
190
191pub struct SourceRecords {
192 ptr: UniquePtr<raw::SourceRecords>,
193 parser: RefCell<UniquePtr<raw::SourceParser>>,
194}
195
196impl SourceRecords {
197 pub fn new(ptr: UniquePtr<raw::SourceRecords>) -> SourceRecords {
198 SourceRecords {
199 ptr,
200 parser: RefCell::new(UniquePtr::null()),
201 }
202 }
203
204 pub fn restart(&self) { self.ptr.restart() }
206
207 pub fn lookup(&self, name: String, src_only: bool) -> Option<SourceParser<'_>> {
224 unsafe {
225 self.parser.replace(self.ptr.find(name, src_only));
226 }
227
228 if self.parser.borrow().end() {
229 self.restart();
230 return None;
231 }
232 Some(self.parser.borrow())
233 }
234}
235
236#[cxx::bridge]
237pub(crate) mod raw {
238 impl UniquePtr<IndexFile> {}
239 impl UniquePtr<SourceRecords> {}
240 unsafe extern "C++" {
241 include!("rust-apt/apt-pkg-c/records.h");
242 type PkgRecords;
243 type Parser;
244 type SourceRecords;
245 type SourceParser;
246 type IndexFile;
247 type VerFileIterator = crate::iterators::VerFileIterator;
248 type DescIterator = crate::iterators::DescIterator;
249
250 unsafe fn ver_lookup(self: &PkgRecords, ver_file: &VerFileIterator) -> UniquePtr<Parser>;
260
261 unsafe fn desc_lookup(self: &PkgRecords, desc_file: &DescIterator) -> UniquePtr<Parser>;
271
272 pub fn filename(self: &Parser) -> String;
273 pub fn long_desc(self: &Parser) -> Result<String>;
274 pub fn short_desc(self: &Parser) -> Result<String>;
275
276 pub fn get_field(self: &Parser, field: String) -> Result<String>;
277 pub fn hash_find(self: &Parser, hash_type: String) -> Result<String>;
278
279 pub fn archive_uri(self: &IndexFile, filename: &str) -> String;
280
281 pub fn is_trusted(self: &IndexFile) -> bool;
283
284 pub fn restart(self: &SourceRecords);
285
286 unsafe fn find(
291 self: &SourceRecords,
292 name: String,
293 src_only: bool,
294 ) -> UniquePtr<SourceParser>;
295
296 fn as_str(self: &SourceParser) -> String;
297 fn package(self: &SourceParser) -> String;
298 fn version(self: &SourceParser) -> String;
299 fn maintainer(self: &SourceParser) -> String;
300 fn section(self: &SourceParser) -> String;
301 fn end(self: &SourceParser) -> bool;
302 }
303}