1use std::cmp::Ordering;
2use std::ffi::{c_char, c_int, CString};
3use std::ops::Deref;
4use std::ptr;
5
6use pkgcraft::dep;
7use pkgcraft::utils::hash;
8
9use crate::macros::*;
10use crate::panic::ffi_catch_panic;
11use crate::utils::boxed;
12
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct UseDepWrapper(dep::UseDep);
16
17#[derive(Debug, Clone)]
19#[repr(C)]
20pub struct UseDep {
21 flag: *mut c_char,
22 kind: dep::UseDepKind,
23 enabled: bool,
24 default_: *mut bool,
26 dep: *mut UseDepWrapper,
27}
28
29impl From<dep::UseDep> for UseDep {
30 fn from(u: dep::UseDep) -> Self {
31 UseDep {
32 kind: u.kind(),
33 enabled: u.enabled(),
34 flag: try_ptr_from_str!(u.flag()),
35 default_: u.default().map(boxed).unwrap_or(ptr::null_mut()),
36 dep: boxed(UseDepWrapper(u)),
37 }
38 }
39}
40
41impl Deref for UseDep {
42 type Target = dep::UseDep;
43
44 fn deref(&self) -> &Self::Target {
45 let wrapper = try_ref_from_ptr!(self.dep);
46 &wrapper.0
47 }
48}
49
50impl Drop for UseDep {
51 fn drop(&mut self) {
52 unsafe {
53 drop(CString::from_raw(self.flag));
54 if !self.default_.is_null() {
55 drop(Box::from_raw(self.default_));
56 }
57 drop(Box::from_raw(self.dep));
58 }
59 }
60}
61
62#[no_mangle]
69pub unsafe extern "C" fn pkgcraft_use_dep_new(s: *const c_char) -> *mut UseDep {
70 ffi_catch_panic! {
71 let s = try_str_from_ptr!(s);
72 let use_dep = unwrap_or_panic!(dep::UseDep::try_new(s).map(|u| u.into()));
73 Box::into_raw(Box::new(use_dep))
74 }
75}
76
77#[no_mangle]
83pub unsafe extern "C" fn pkgcraft_use_dep_cmp(u1: *mut UseDep, u2: *mut UseDep) -> c_int {
84 let u1 = try_ref_from_ptr!(u1);
85 let u2 = try_ref_from_ptr!(u2);
86
87 match u1.cmp(u2) {
88 Ordering::Less => -1,
89 Ordering::Equal => 0,
90 Ordering::Greater => 1,
91 }
92}
93
94#[no_mangle]
99pub unsafe extern "C" fn pkgcraft_use_dep_hash(u: *mut UseDep) -> u64 {
100 let use_dep = try_ref_from_ptr!(u);
101 hash(use_dep.deref())
102}
103
104#[no_mangle]
109pub unsafe extern "C" fn pkgcraft_use_dep_str(u: *mut UseDep) -> *mut c_char {
110 let u = try_ref_from_ptr!(u);
111 try_ptr_from_str!(u.to_string())
112}
113
114#[no_mangle]
119pub unsafe extern "C" fn pkgcraft_use_dep_free(u: *mut UseDep) {
120 if !u.is_null() {
121 unsafe { drop(Box::from_raw(u)) };
122 }
123}