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 PhasedUpdatePercentage: &str = "Phased-Update-Percentage";
126
127 pub const MD5sum: &str = "MD5sum";
129
130 pub const SHA256: &str = "SHA256";
133}
134
135pub struct PackageRecords {
136 pub(crate) ptr: UniquePtr<raw::PkgRecords>,
137 parser: RefCell<UniquePtr<raw::Parser>>,
138 index: RefCell<u64>,
139}
140
141impl PackageRecords {
142 pub fn new(ptr: UniquePtr<raw::PkgRecords>) -> PackageRecords {
143 PackageRecords {
144 ptr,
145 parser: RefCell::new(UniquePtr::null()),
146 index: RefCell::new(0),
147 }
148 }
149
150 fn replace_index(&self, index: u64) -> bool {
151 if self.index.borrow().eq(&index) {
152 return false;
153 }
154 self.index.replace(index);
155 true
156 }
157
158 fn parser(&self) -> Ref<'_, UniquePtr<raw::Parser>> {
159 if self.parser.borrow().is_null() {
160 panic!("You must call ver_lookup or desc_lookup first!")
161 }
162 self.parser.borrow()
163 }
164
165 pub fn ver_lookup(&self, file: &raw::VerFileIterator) -> &PackageRecords {
166 if self.replace_index(file.index()) {
167 unsafe { self.parser.replace(self.ptr.ver_lookup(file)) };
168 }
169 self
170 }
171
172 pub fn desc_lookup(&self, file: &raw::DescIterator) -> &PackageRecords {
173 if self.replace_index(file.index()) {
174 unsafe { self.parser.replace(self.ptr.desc_lookup(file)) };
175 }
176 self
177 }
178
179 pub fn short_desc(&self) -> Option<String> { self.parser().short_desc().ok() }
180
181 pub fn long_desc(&self) -> Option<String> { self.parser().long_desc().ok() }
182
183 pub fn filename(&self) -> String { self.parser().filename() }
184
185 pub fn get_field(&self, field: String) -> Option<String> { self.parser().get_field(field).ok() }
186
187 pub fn hash_find(&self, hash_type: String) -> Option<String> {
188 self.parser().hash_find(hash_type).ok()
189 }
190}
191
192type SourceParser<'a> = Ref<'a, UniquePtr<raw::SourceParser>>;
193
194pub struct SourceRecords {
195 ptr: UniquePtr<raw::SourceRecords>,
196 parser: RefCell<UniquePtr<raw::SourceParser>>,
197}
198
199impl SourceRecords {
200 pub fn new(ptr: UniquePtr<raw::SourceRecords>) -> SourceRecords {
201 SourceRecords {
202 ptr,
203 parser: RefCell::new(UniquePtr::null()),
204 }
205 }
206
207 pub fn restart(&self) { self.ptr.restart() }
209
210 pub fn lookup(&self, name: String, src_only: bool) -> Option<SourceParser<'_>> {
227 unsafe {
228 self.parser.replace(self.ptr.find(name, src_only));
229 }
230
231 if self.parser.borrow().end() {
232 self.restart();
233 return None;
234 }
235 Some(self.parser.borrow())
236 }
237}
238
239#[cxx::bridge]
240pub(crate) mod raw {
241 impl UniquePtr<IndexFile> {}
242 impl UniquePtr<SourceRecords> {}
243 unsafe extern "C++" {
244 include!("rust-apt/apt-pkg-c/records.h");
245 type PkgRecords;
246 type Parser;
247 type SourceRecords;
248 type SourceParser;
249 type IndexFile;
250 type VerFileIterator = crate::iterators::VerFileIterator;
251 type DescIterator = crate::iterators::DescIterator;
252
253 unsafe fn ver_lookup(self: &PkgRecords, ver_file: &VerFileIterator) -> UniquePtr<Parser>;
263
264 unsafe fn desc_lookup(self: &PkgRecords, desc_file: &DescIterator) -> UniquePtr<Parser>;
274
275 pub fn filename(self: &Parser) -> String;
276 pub fn long_desc(self: &Parser) -> Result<String>;
277 pub fn short_desc(self: &Parser) -> Result<String>;
278
279 pub fn get_field(self: &Parser, field: String) -> Result<String>;
280 pub fn hash_find(self: &Parser, hash_type: String) -> Result<String>;
281
282 pub fn archive_uri(self: &IndexFile, filename: &str) -> String;
283 pub fn describe(self: &IndexFile, short_desc: bool) -> String;
284
285 pub fn is_trusted(self: &IndexFile) -> bool;
287
288 pub fn restart(self: &SourceRecords);
289
290 unsafe fn find(
295 self: &SourceRecords,
296 name: String,
297 src_only: bool,
298 ) -> UniquePtr<SourceParser>;
299
300 fn as_str(self: &SourceParser) -> String;
301 fn package(self: &SourceParser) -> String;
302 fn version(self: &SourceParser) -> String;
303 fn maintainer(self: &SourceParser) -> String;
304 fn section(self: &SourceParser) -> String;
305 fn end(self: &SourceParser) -> bool;
306 }
307}