1#![warn(rust_2018_idioms)]
39#![deny(missing_docs)]
40
41#[cfg(any(
42 not(any(feature = "runtime", feature = "compile-time")),
43 all(feature = "runtime", feature = "compile-time")
44))]
45compile_error!("Exactly one of the features `runtime` or `compile-time` is required.");
46
47#[cfg(any(feature = "runtime", feature = "compile-time"))]
48mod ffi_types;
49
50#[cfg(feature = "compile-time")]
51mod ffi;
52
53#[allow(clippy::missing_safety_doc)]
58#[cfg(feature = "compile-time")]
59pub unsafe fn count() -> Option<u32> {
60 use ffi::*;
61 use ffi_types::*;
62
63 if rpmReadConfigFiles(std::ptr::null(), std::ptr::null()) != 0 {
64 return None;
65 }
66
67 let ts = rpmtsCreate();
68 if ts.is_null() {
69 return None;
70 }
71
72 let mi = rpmtsInitIterator(ts, rpmDbiTag_e_RPMDBI_LABEL as i32, std::ptr::null(), 0);
73 if mi.is_null() {
74 rpmtsFree(ts);
75 return None;
76 }
77
78 let count = rpmdbGetIteratorCount(mi);
79
80 rpmdbFreeIterator(mi);
81 rpmtsFree(ts);
82
83 Some(count as u32)
84}
85
86#[allow(clippy::missing_safety_doc, non_snake_case)]
91#[cfg(feature = "runtime")]
92pub unsafe fn count() -> Option<u32> {
93 use ffi_types::*;
94 use libloading::{Library, Symbol};
95
96 let lib = Library::new(libloading::library_filename("rpm")).ok()?;
98
99 let rpmReadConfigFiles: Symbol<
101 '_,
102 unsafe extern "C" fn(
103 file: *const ::std::os::raw::c_char,
104 target: *const ::std::os::raw::c_char,
105 ) -> ::std::os::raw::c_int,
106 > = lib.get(b"rpmReadConfigFiles").ok()?;
107 let rpmdbFreeIterator: Symbol<
108 '_,
109 unsafe extern "C" fn(mi: rpmdbMatchIterator) -> rpmdbMatchIterator,
110 > = lib.get(b"rpmdbFreeIterator").ok()?;
111 let rpmdbGetIteratorCount: Symbol<
112 '_,
113 unsafe extern "C" fn(mi: rpmdbMatchIterator) -> ::std::os::raw::c_int,
114 > = lib.get(b"rpmdbGetIteratorCount").ok()?;
115 let rpmtsCreate: Symbol<'_, unsafe extern "C" fn() -> rpmts> = lib.get(b"rpmtsCreate").ok()?;
116 let rpmtsFree: Symbol<'_, unsafe extern "C" fn(ts: rpmts) -> rpmts> =
117 lib.get(b"rpmtsFree").ok()?;
118 let rpmtsInitIterator: Symbol<
119 '_,
120 unsafe extern "C" fn(
121 ts: rpmts,
122 rpmtag: rpmDbiTagVal,
123 keyp: *const ::std::os::raw::c_void,
124 keylen: size_t,
125 ) -> rpmdbMatchIterator,
126 > = lib.get(b"rpmtsInitIterator").ok()?;
127
128 if rpmReadConfigFiles(std::ptr::null(), std::ptr::null()) != 0 {
129 return None;
130 }
131
132 let ts = rpmtsCreate();
133 if ts.is_null() {
134 return None;
135 }
136
137 let mi = rpmtsInitIterator(ts, rpmDbiTag_e_RPMDBI_LABEL as i32, std::ptr::null(), 0);
138 if mi.is_null() {
139 rpmtsFree(ts);
140 return None;
141 }
142
143 let count = rpmdbGetIteratorCount(mi);
144
145 rpmdbFreeIterator(mi);
146 rpmtsFree(ts);
147
148 Some(count as u32)
149}