1use std::borrow::Cow;
2use std::cmp::Ordering;
3use std::ffi::{c_char, c_int};
4use std::{ptr, slice};
5
6use pkgcraft::dep::{Blocker, Cpn, Cpv, Dep, DepField, SlotOperator, Version};
7use pkgcraft::eapi::Eapi;
8use pkgcraft::restrict::{Restrict, Restriction};
9use pkgcraft::traits::Intersects;
10use pkgcraft::utils::hash;
11
12use crate::eapi::eapi_or_default;
13use crate::macros::*;
14use crate::panic::ffi_catch_panic;
15use crate::utils::{boxed, obj_to_str};
16
17use super::use_dep::UseDep;
18
19#[no_mangle]
27pub unsafe extern "C" fn pkgcraft_dep_new(s: *const c_char, eapi: *const Eapi) -> *mut Dep {
28 ffi_catch_panic! {
29 let s = try_str_from_ptr!(s);
30 let eapi = eapi_or_default!(eapi);
31 let dep = unwrap_or_panic!(eapi.dep(s));
32 Box::into_raw(Box::new(dep))
33 }
34}
35
36#[no_mangle]
43pub unsafe extern "C" fn pkgcraft_dep_parse(s: *const c_char, eapi: *const Eapi) -> *const c_char {
44 ffi_catch_panic! {
45 let val = try_str_from_ptr!(s);
46 let eapi = option_from_ptr!(eapi).unwrap_or_default();
47 unwrap_or_panic!(eapi.dep(val));
48 s
49 }
50}
51
52#[no_mangle]
59pub unsafe extern "C" fn pkgcraft_dep_without(
60 d: *mut Dep,
61 fields: *mut DepField,
62 len: usize,
63) -> *mut Dep {
64 ffi_catch_panic! {
65 let dep = try_ref_from_ptr!(d);
66 let fields = unsafe { slice::from_raw_parts(fields, len) };
67 let dep = dep.without(fields.iter().copied());
68
69 if let Cow::Owned(d) = unwrap_or_panic!(dep) {
70 Box::into_raw(Box::new(d))
71 } else {
72 d
73 }
74 }
75}
76
77#[no_mangle]
82pub unsafe extern "C" fn pkgcraft_dep_unversioned(d: *mut Dep) -> *mut Dep {
83 let dep = try_ref_from_ptr!(d);
84 if let Cow::Owned(d) = dep.unversioned() {
85 Box::into_raw(Box::new(d))
86 } else {
87 d
88 }
89}
90
91#[no_mangle]
96pub unsafe extern "C" fn pkgcraft_dep_versioned(d: *mut Dep) -> *mut Dep {
97 let dep = try_ref_from_ptr!(d);
98 if let Cow::Owned(d) = dep.versioned() {
99 Box::into_raw(Box::new(d))
100 } else {
101 d
102 }
103}
104
105#[no_mangle]
110pub unsafe extern "C" fn pkgcraft_dep_no_use_deps(d: *mut Dep) -> *mut Dep {
111 let dep = try_ref_from_ptr!(d);
112 if let Cow::Owned(d) = dep.no_use_deps() {
113 Box::into_raw(Box::new(d))
114 } else {
115 d
116 }
117}
118
119#[no_mangle]
128pub unsafe extern "C" fn pkgcraft_dep_modify(
129 d: *mut Dep,
130 fields: *mut DepField,
131 values: *mut *mut c_char,
132 len: usize,
133) -> *mut Dep {
134 ffi_catch_panic! {
135 let dep = try_ref_from_ptr!(d);
136 let fields = unsafe { slice::from_raw_parts(fields, len) };
137 let values = unsafe { slice::from_raw_parts(values, len) };
138 let iterable = fields.iter().zip(values.iter())
139 .map(|(f, p)| (*f, option_from_ptr!(p).map(|_| try_str_from_ptr!(p))));
140
141 if let Cow::Owned(d) = unwrap_or_panic!(dep.modify(iterable)) {
142 Box::into_raw(Box::new(d))
143 } else {
144 d
145 }
146 }
147}
148
149#[no_mangle]
156pub unsafe extern "C" fn pkgcraft_dep_blocker_from_str(s: *const c_char) -> u32 {
157 let s = try_str_from_ptr!(s);
158 s.parse::<Blocker>().map(|x| x as u32).unwrap_or_default()
159}
160
161#[no_mangle]
163pub extern "C" fn pkgcraft_dep_blocker_str(b: Blocker) -> *mut c_char {
164 try_ptr_from_str!(b.as_ref())
165}
166
167#[no_mangle]
174pub unsafe extern "C" fn pkgcraft_dep_slot_op_from_str(s: *const c_char) -> u32 {
175 let s = try_str_from_ptr!(s);
176 s.parse::<SlotOperator>()
177 .map(|x| x as u32)
178 .unwrap_or_default()
179}
180
181#[no_mangle]
183pub extern "C" fn pkgcraft_dep_slot_op_str(op: SlotOperator) -> *mut c_char {
184 try_ptr_from_str!(op.as_ref())
185}
186
187#[no_mangle]
193pub unsafe extern "C" fn pkgcraft_dep_cmp(d1: *mut Dep, d2: *mut Dep) -> c_int {
194 let d1 = try_ref_from_ptr!(d1);
195 let d2 = try_ref_from_ptr!(d2);
196
197 match d1.cmp(d2) {
198 Ordering::Less => -1,
199 Ordering::Equal => 0,
200 Ordering::Greater => 1,
201 }
202}
203
204#[no_mangle]
209pub unsafe extern "C" fn pkgcraft_dep_intersects(d1: *mut Dep, d2: *mut Dep) -> bool {
210 let d1 = try_ref_from_ptr!(d1);
211 let d2 = try_ref_from_ptr!(d2);
212 d1.intersects(d2)
213}
214
215#[no_mangle]
220pub unsafe extern "C" fn pkgcraft_dep_intersects_cpv(d: *mut Dep, c: *mut Cpv) -> bool {
221 let d = try_ref_from_ptr!(d);
222 let c = try_ref_from_ptr!(c);
223 d.intersects(c)
224}
225
226#[no_mangle]
232pub unsafe extern "C" fn pkgcraft_dep_category(d: *mut Dep) -> *mut c_char {
233 let dep = try_ref_from_ptr!(d);
234 try_ptr_from_str!(dep.category())
235}
236
237#[no_mangle]
243pub unsafe extern "C" fn pkgcraft_dep_package(d: *mut Dep) -> *mut c_char {
244 let dep = try_ref_from_ptr!(d);
245 try_ptr_from_str!(dep.package())
246}
247
248#[no_mangle]
256pub unsafe extern "C" fn pkgcraft_dep_blocker(d: *mut Dep) -> u32 {
257 let dep = try_ref_from_ptr!(d);
258 dep.blocker().map(|x| x as u32).unwrap_or_default()
259}
260
261#[no_mangle]
269pub unsafe extern "C" fn pkgcraft_dep_version(d: *mut Dep) -> *mut Version {
270 let dep = try_ref_from_ptr!(d);
271 match dep.version() {
272 Some(v) => Box::into_raw(Box::new(v.clone())),
273 None => ptr::null_mut(),
274 }
275}
276
277#[no_mangle]
285pub unsafe extern "C" fn pkgcraft_dep_slot(d: *mut Dep) -> *mut c_char {
286 let dep = try_ref_from_ptr!(d);
287 match dep.slot() {
288 Some(s) => try_ptr_from_str!(s),
289 None => ptr::null_mut(),
290 }
291}
292
293#[no_mangle]
301pub unsafe extern "C" fn pkgcraft_dep_subslot(d: *mut Dep) -> *mut c_char {
302 let dep = try_ref_from_ptr!(d);
303 match dep.subslot() {
304 Some(s) => try_ptr_from_str!(s),
305 None => ptr::null_mut(),
306 }
307}
308
309#[no_mangle]
317pub unsafe extern "C" fn pkgcraft_dep_slot_op(d: *mut Dep) -> u32 {
318 let dep = try_ref_from_ptr!(d);
319 dep.slot_op().map(|x| x as u32).unwrap_or_default()
320}
321
322#[no_mangle]
330pub unsafe extern "C" fn pkgcraft_dep_use_deps(d: *mut Dep, len: *mut usize) -> *mut *mut UseDep {
331 let dep = try_ref_from_ptr!(d);
333 match dep.use_deps() {
334 Some(use_deps) => iter_to_array!(use_deps.iter(), len, |u| boxed(u.clone().into())),
335 None => ptr::null_mut(),
336 }
337}
338
339#[no_mangle]
347pub unsafe extern "C" fn pkgcraft_dep_use_deps_str(
348 d: *mut Dep,
349 len: *mut usize,
350) -> *mut *mut c_char {
351 let dep = try_ref_from_ptr!(d);
353 match dep.use_deps() {
354 Some(use_deps) => iter_to_array!(use_deps.iter(), len, obj_to_str),
355 None => ptr::null_mut(),
356 }
357}
358
359#[no_mangle]
367pub unsafe extern "C" fn pkgcraft_dep_repo(d: *mut Dep) -> *mut c_char {
368 let dep = try_ref_from_ptr!(d);
369 match dep.repo() {
370 Some(s) => try_ptr_from_str!(s),
371 None => ptr::null_mut(),
372 }
373}
374
375#[no_mangle]
380pub unsafe extern "C" fn pkgcraft_dep_cpn(d: *mut Dep) -> *mut Cpn {
381 let dep = try_ref_from_ptr!(d);
382 Box::into_raw(Box::new(dep.cpn().clone()))
383}
384
385#[no_mangle]
392pub unsafe extern "C" fn pkgcraft_dep_cpv(d: *mut Dep) -> *mut Cpv {
393 let dep = try_ref_from_ptr!(d);
394 match dep.cpv() {
395 Some(cpv) => Box::into_raw(Box::new(cpv)),
396 None => ptr::null_mut(),
397 }
398}
399
400#[no_mangle]
405pub unsafe extern "C" fn pkgcraft_dep_str(d: *mut Dep) -> *mut c_char {
406 let dep = try_ref_from_ptr!(d);
407 try_ptr_from_str!(dep.to_string())
408}
409
410#[no_mangle]
415pub unsafe extern "C" fn pkgcraft_dep_hash(d: *mut Dep) -> u64 {
416 let dep = try_ref_from_ptr!(d);
417 hash(dep)
418}
419
420#[no_mangle]
425pub unsafe extern "C" fn pkgcraft_dep_restrict(d: *mut Dep) -> *mut Restrict {
426 let dep = try_ref_from_ptr!(d);
427 Box::into_raw(Box::new(dep.into()))
428}
429
430#[no_mangle]
435pub unsafe extern "C" fn pkgcraft_dep_restrict_matches(d: *mut Dep, r: *mut Restrict) -> bool {
436 let dep = try_ref_from_ptr!(d);
437 let restrict = try_ref_from_ptr!(r);
438 restrict.matches(dep)
439}
440
441#[no_mangle]
446pub unsafe extern "C" fn pkgcraft_dep_free(d: *mut Dep) {
447 if !d.is_null() {
448 unsafe { drop(Box::from_raw(d)) };
449 }
450}