1use std::cmp::Ordering;
2use std::ffi::{c_char, c_int};
3use std::{ptr, slice};
4
5use pkgcraft::dep::Version;
6use pkgcraft::pkg::Pkg;
7use pkgcraft::repo::set::RepoSet;
8use pkgcraft::repo::{PkgRepository, Repo};
9use pkgcraft::restrict::Restrict;
10use pkgcraft::utils::hash;
11
12use crate::macros::*;
13use crate::types::{RepoSetIter, SetOp};
14use crate::utils::{boxed, str_to_raw};
15
16#[no_mangle]
21pub unsafe extern "C" fn pkgcraft_repo_set_new(repos: *mut *mut Repo, len: usize) -> *mut RepoSet {
22 let repos = unsafe { slice::from_raw_parts(repos, len) };
23 let repos = repos.iter().map(|r| try_ref_from_ptr!(r));
24 Box::into_raw(Box::new(repos.collect()))
25}
26
27#[no_mangle]
32pub unsafe extern "C" fn pkgcraft_repo_set_categories(
33 s: *mut RepoSet,
34 len: *mut usize,
35) -> *mut *mut c_char {
36 let s = try_ref_from_ptr!(s);
37 iter_to_array!(s.categories().iter(), len, str_to_raw)
38}
39
40#[no_mangle]
45pub unsafe extern "C" fn pkgcraft_repo_set_packages(
46 s: *mut RepoSet,
47 cat: *const c_char,
48 len: *mut usize,
49) -> *mut *mut c_char {
50 let s = try_ref_from_ptr!(s);
51 let cat = try_str_from_ptr!(cat);
52 iter_to_array!(s.packages(cat).iter(), len, str_to_raw)
53}
54
55#[no_mangle]
60pub unsafe extern "C" fn pkgcraft_repo_set_versions(
61 s: *mut RepoSet,
62 cat: *const c_char,
63 pkg: *const c_char,
64 len: *mut usize,
65) -> *mut *mut Version {
66 let s = try_ref_from_ptr!(s);
67 let cat = try_str_from_ptr!(cat);
68 let pkg = try_str_from_ptr!(pkg);
69 iter_to_array!(s.versions(cat, pkg).into_iter(), len, boxed)
70}
71
72#[no_mangle]
77pub unsafe extern "C" fn pkgcraft_repo_set_len(s: *mut RepoSet) -> usize {
78 let s = try_ref_from_ptr!(s);
79 s.len()
80}
81
82#[no_mangle]
87pub unsafe extern "C" fn pkgcraft_repo_set_is_empty(s: *mut RepoSet) -> bool {
88 let s = try_ref_from_ptr!(s);
89 s.is_empty()
90}
91
92#[no_mangle]
97pub unsafe extern "C" fn pkgcraft_repo_set_repos(
98 s: *mut RepoSet,
99 len: *mut usize,
100) -> *mut *const Repo {
101 let s = try_ref_from_ptr!(s);
102 iter_to_array!(s.repos.iter(), len, |r| { r as *const _ })
103}
104
105#[no_mangle]
111pub unsafe extern "C" fn pkgcraft_repo_set_cmp(s1: *mut RepoSet, s2: *mut RepoSet) -> c_int {
112 let s1 = try_ref_from_ptr!(s1);
113 let s2 = try_ref_from_ptr!(s2);
114
115 match s1.cmp(s2) {
116 Ordering::Less => -1,
117 Ordering::Equal => 0,
118 Ordering::Greater => 1,
119 }
120}
121
122#[no_mangle]
127pub unsafe extern "C" fn pkgcraft_repo_set_hash(s: *mut RepoSet) -> u64 {
128 let s = try_ref_from_ptr!(s);
129 hash(s)
130}
131
132#[no_mangle]
137pub unsafe extern "C" fn pkgcraft_repo_set_free(r: *mut RepoSet) {
138 if !r.is_null() {
139 unsafe { drop(Box::from_raw(r)) };
140 }
141}
142
143#[no_mangle]
149pub unsafe extern "C" fn pkgcraft_repo_set_iter<'a>(
150 s: *mut RepoSet,
151 restrict: *mut Restrict,
152) -> *mut RepoSetIter<'a> {
153 let s = try_ref_from_ptr!(s);
154 let iter = match unsafe { restrict.as_ref() } {
155 Some(r) => s.iter_restrict(r.clone()),
156 None => s.iter(),
157 };
158 Box::into_raw(Box::new(iter))
159}
160
161#[no_mangle]
168pub unsafe extern "C" fn pkgcraft_repo_set_iter_next(i: *mut RepoSetIter) -> *mut Pkg {
169 let iter = try_mut_from_ptr!(i);
170 iter.next().map(boxed).unwrap_or(ptr::null_mut())
171}
172
173#[no_mangle]
178pub unsafe extern "C" fn pkgcraft_repo_set_iter_free(i: *mut RepoSetIter) {
179 if !i.is_null() {
180 unsafe { drop(Box::from_raw(i)) };
181 }
182}
183
184#[no_mangle]
189pub unsafe extern "C" fn pkgcraft_repo_set_assign_op_set(
190 op: SetOp,
191 s1: *mut RepoSet,
192 s2: *mut RepoSet,
193) {
194 use SetOp::*;
195 let s1 = try_mut_from_ptr!(s1);
196 let s2 = try_ref_from_ptr!(s2);
197 match op {
198 And => *s1 &= s2,
199 Or => *s1 |= s2,
200 Xor => *s1 ^= s2,
201 Sub => *s1 -= s2,
202 }
203}
204
205#[no_mangle]
210pub unsafe extern "C" fn pkgcraft_repo_set_assign_op_repo(
211 op: SetOp,
212 s: *mut RepoSet,
213 r: *mut Repo,
214) {
215 use SetOp::*;
216 let s = try_mut_from_ptr!(s);
217 let r = try_ref_from_ptr!(r);
218 match op {
219 And => *s &= r,
220 Or => *s |= r,
221 Xor => *s ^= r,
222 Sub => *s -= r,
223 }
224}
225
226#[no_mangle]
231pub unsafe extern "C" fn pkgcraft_repo_set_op_set(
232 op: SetOp,
233 s1: *mut RepoSet,
234 s2: *mut RepoSet,
235) -> *mut RepoSet {
236 use SetOp::*;
237 let s1 = try_mut_from_ptr!(s1);
238 let s2 = try_ref_from_ptr!(s2);
239 let set = match op {
240 And => s1.clone() & s2,
241 Or => s1.clone() | s2,
242 Xor => s1.clone() ^ s2,
243 Sub => s1.clone() - s2,
244 };
245 Box::into_raw(Box::new(set))
246}
247
248#[no_mangle]
253pub unsafe extern "C" fn pkgcraft_repo_set_op_repo(
254 op: SetOp,
255 s: *mut RepoSet,
256 r: *mut Repo,
257) -> *mut RepoSet {
258 use SetOp::*;
259 let s = try_mut_from_ptr!(s);
260 let r = try_ref_from_ptr!(r);
261 let set = match op {
262 And => s.clone() & r,
263 Or => s.clone() | r,
264 Xor => s.clone() ^ r,
265 Sub => s.clone() - r,
266 };
267 Box::into_raw(Box::new(set))
268}