pkgcraft/
dep.rs

1use std::cmp::Ordering;
2use std::ffi::{c_char, c_int, c_void};
3use std::hash::{Hash, Hasher};
4use std::ops::{
5    BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, DerefMut, Sub, SubAssign,
6};
7use std::{fmt, ptr, slice};
8
9use pkgcraft::dep::{self, Conditionals, Dep, Evaluate, EvaluateForce, Flatten, Recursive, Uri};
10use pkgcraft::eapi::Eapi;
11use pkgcraft::traits::{Contains, IntoOwned};
12use pkgcraft::types::Ordered;
13use pkgcraft::utils::hash;
14
15use crate::eapi::eapi_or_default;
16use crate::error::Error;
17use crate::macros::*;
18use crate::panic::ffi_catch_panic;
19use crate::types::SetOp;
20use crate::utils::boxed;
21
22pub mod cpn;
23pub mod cpv;
24pub mod pkg;
25pub mod uri;
26pub mod use_dep;
27pub mod version;
28
29/// DependencySet variants.
30#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
31#[repr(C)]
32pub enum DependencySetKind {
33    Package,
34    SrcUri,
35    License,
36    Properties,
37    RequiredUse,
38    Restrict,
39}
40
41/// Opaque wrapper for pkgcraft::dep::DependencySet.
42#[derive(Debug, Clone, PartialEq, Eq, Hash)]
43pub enum DependencySetWrapper {
44    Dep(dep::DependencySet<Dep>),
45    String(dep::DependencySet<String>),
46    Uri(dep::DependencySet<Uri>),
47}
48
49impl fmt::Display for DependencySetWrapper {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        match self {
52            Self::Dep(d) => write!(f, "{d}"),
53            Self::String(d) => write!(f, "{d}"),
54            Self::Uri(d) => write!(f, "{d}"),
55        }
56    }
57}
58
59/// C-compatible wrapper for pkgcraft::dep::DependencySet.
60#[derive(Debug)]
61#[repr(C)]
62pub struct DependencySet {
63    set: DependencySetKind,
64    dep: *mut DependencySetWrapper,
65}
66
67impl Clone for DependencySet {
68    fn clone(&self) -> Self {
69        let dep = try_ref_from_ptr!(self.dep);
70        Self {
71            set: self.set,
72            dep: Box::into_raw(Box::new(dep.clone())),
73        }
74    }
75}
76
77impl Drop for DependencySet {
78    fn drop(&mut self) {
79        unsafe {
80            drop(Box::from_raw(self.dep));
81        }
82    }
83}
84
85impl DependencySet {
86    pub(crate) fn new_dep(d: dep::DependencySet<Dep>) -> Self {
87        Self {
88            set: DependencySetKind::Package,
89            dep: Box::into_raw(Box::new(DependencySetWrapper::Dep(d))),
90        }
91    }
92
93    pub(crate) fn new_string(d: dep::DependencySet<String>, set: DependencySetKind) -> Self {
94        Self {
95            set,
96            dep: Box::into_raw(Box::new(DependencySetWrapper::String(d))),
97        }
98    }
99
100    pub(crate) fn new_uri(d: dep::DependencySet<Uri>) -> Self {
101        Self {
102            set: DependencySetKind::SrcUri,
103            dep: Box::into_raw(Box::new(DependencySetWrapper::Uri(d))),
104        }
105    }
106}
107
108impl Hash for DependencySet {
109    fn hash<H: Hasher>(&self, state: &mut H) {
110        self.deref().hash(state)
111    }
112}
113
114impl PartialEq for DependencySet {
115    fn eq(&self, other: &Self) -> bool {
116        self.deref().eq(other.deref())
117    }
118}
119
120impl Eq for DependencySet {}
121
122impl Deref for DependencySet {
123    type Target = DependencySetWrapper;
124
125    fn deref(&self) -> &Self::Target {
126        try_ref_from_ptr!(self.dep)
127    }
128}
129
130impl DerefMut for DependencySet {
131    fn deref_mut(&mut self) -> &mut Self::Target {
132        try_mut_from_ptr!(self.dep)
133    }
134}
135
136impl fmt::Display for DependencySet {
137    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138        write!(f, "{}", self.deref())
139    }
140}
141
142impl BitAnd<&DependencySet> for &DependencySet {
143    type Output = DependencySet;
144
145    fn bitand(self, other: &DependencySet) -> Self::Output {
146        let mut dep = self.clone();
147        dep &= other;
148        dep
149    }
150}
151
152impl BitAndAssign<&DependencySet> for DependencySet {
153    fn bitand_assign(&mut self, other: &DependencySet) {
154        use DependencySetWrapper::*;
155        match (self.deref_mut(), other.deref()) {
156            (Dep(d1), Dep(d2)) => *d1 &= d2,
157            (String(d1), String(d2)) => *d1 &= d2,
158            (Uri(d1), Uri(d2)) => *d1 &= d2,
159            _ => {
160                set_error_and_panic!(Error::new(format!(
161                    "DependencySet kind {:?} doesn't match: {:?}",
162                    self.set, other.set
163                )));
164            }
165        }
166    }
167}
168
169impl BitOr<&DependencySet> for &DependencySet {
170    type Output = DependencySet;
171
172    fn bitor(self, other: &DependencySet) -> Self::Output {
173        let mut dep = self.clone();
174        dep |= other;
175        dep
176    }
177}
178
179impl BitOrAssign<&DependencySet> for DependencySet {
180    fn bitor_assign(&mut self, other: &DependencySet) {
181        use DependencySetWrapper::*;
182        match (self.deref_mut(), other.deref()) {
183            (Dep(d1), Dep(d2)) => *d1 |= d2,
184            (String(d1), String(d2)) => *d1 |= d2,
185            (Uri(d1), Uri(d2)) => *d1 |= d2,
186            _ => {
187                set_error_and_panic!(Error::new(format!(
188                    "DependencySet kind {:?} doesn't match: {:?}",
189                    self.set, other.set
190                )));
191            }
192        }
193    }
194}
195
196impl BitXor<&DependencySet> for &DependencySet {
197    type Output = DependencySet;
198
199    fn bitxor(self, other: &DependencySet) -> Self::Output {
200        let mut dep = self.clone();
201        dep ^= other;
202        dep
203    }
204}
205
206impl BitXorAssign<&DependencySet> for DependencySet {
207    fn bitxor_assign(&mut self, other: &DependencySet) {
208        use DependencySetWrapper::*;
209        match (self.deref_mut(), other.deref()) {
210            (Dep(d1), Dep(d2)) => *d1 ^= d2,
211            (String(d1), String(d2)) => *d1 ^= d2,
212            (Uri(d1), Uri(d2)) => *d1 ^= d2,
213            _ => {
214                set_error_and_panic!(Error::new(format!(
215                    "DependencySet kind {:?} doesn't match: {:?}",
216                    self.set, other.set
217                )));
218            }
219        }
220    }
221}
222
223impl Sub<&DependencySet> for &DependencySet {
224    type Output = DependencySet;
225
226    fn sub(self, other: &DependencySet) -> Self::Output {
227        let mut dep = self.clone();
228        dep -= other;
229        dep
230    }
231}
232
233impl SubAssign<&DependencySet> for DependencySet {
234    fn sub_assign(&mut self, other: &DependencySet) {
235        use DependencySetWrapper::*;
236        match (self.deref_mut(), other.deref()) {
237            (Dep(d1), Dep(d2)) => *d1 -= d2,
238            (String(d1), String(d2)) => *d1 -= d2,
239            (Uri(d1), Uri(d2)) => *d1 -= d2,
240            _ => {
241                set_error_and_panic!(Error::new(format!(
242                    "DependencySet kind {:?} doesn't match: {:?}",
243                    self.set, other.set
244                )));
245            }
246        }
247    }
248}
249
250/// Opaque wrapper for pkgcraft::dep::IntoIter<T>.
251#[derive(Debug)]
252pub enum DependencyIntoIter {
253    Dep(DependencySetKind, dep::IntoIter<Dep>),
254    String(DependencySetKind, dep::IntoIter<String>),
255    Uri(DependencySetKind, dep::IntoIter<Uri>),
256}
257
258impl Iterator for DependencyIntoIter {
259    type Item = Dependency;
260
261    fn next(&mut self) -> Option<Self::Item> {
262        match self {
263            Self::Dep(_, iter) => iter.next().map(Dependency::new_dep),
264            Self::String(set, iter) => iter.next().map(|d| Dependency::new_string(d, *set)),
265            Self::Uri(_, iter) => iter.next().map(Dependency::new_uri),
266        }
267    }
268}
269
270impl DoubleEndedIterator for DependencyIntoIter {
271    fn next_back(&mut self) -> Option<Self::Item> {
272        match self {
273            Self::Dep(_, iter) => iter.next_back().map(Dependency::new_dep),
274            Self::String(set, iter) => iter.next_back().map(|d| Dependency::new_string(d, *set)),
275            Self::Uri(_, iter) => iter.next_back().map(Dependency::new_uri),
276        }
277    }
278}
279
280/// Opaque wrapper for pkgcraft::dep::Dependency.
281#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
282pub enum DependencyWrapper {
283    Dep(dep::Dependency<Dep>),
284    String(dep::Dependency<String>),
285    Uri(dep::Dependency<Uri>),
286}
287
288impl fmt::Display for DependencyWrapper {
289    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290        match self {
291            Self::Dep(d) => write!(f, "{d}"),
292            Self::String(d) => write!(f, "{d}"),
293            Self::Uri(d) => write!(f, "{d}"),
294        }
295    }
296}
297
298/// Dependency variants.
299#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
300#[repr(C)]
301pub enum DependencyKind {
302    Enabled,
303    Disabled,
304    AllOf,
305    AnyOf,
306    ExactlyOneOf,
307    AtMostOneOf,
308    Conditional,
309}
310
311impl<T: Ordered> From<&dep::Dependency<T>> for DependencyKind {
312    fn from(d: &dep::Dependency<T>) -> Self {
313        use dep::Dependency::*;
314        match d {
315            Enabled(_) => Self::Enabled,
316            Disabled(_) => Self::Disabled,
317            AllOf(_) => Self::AllOf,
318            AnyOf(_) => Self::AnyOf,
319            ExactlyOneOf(_) => Self::ExactlyOneOf,
320            AtMostOneOf(_) => Self::AtMostOneOf,
321            Conditional(_, _) => Self::Conditional,
322        }
323    }
324}
325
326/// C-compatible wrapper for pkgcraft::dep::Dependency.
327#[derive(Debug, Clone)]
328#[repr(C)]
329pub struct Dependency {
330    set: DependencySetKind,
331    kind: DependencyKind,
332    dep: *mut DependencyWrapper,
333}
334
335impl Drop for Dependency {
336    fn drop(&mut self) {
337        unsafe {
338            drop(Box::from_raw(self.dep));
339        }
340    }
341}
342
343impl Dependency {
344    pub(crate) fn new_dep(d: dep::Dependency<Dep>) -> Self {
345        Self {
346            set: DependencySetKind::Package,
347            kind: DependencyKind::from(&d),
348            dep: Box::into_raw(Box::new(DependencyWrapper::Dep(d))),
349        }
350    }
351
352    pub(crate) fn new_string(d: dep::Dependency<String>, set: DependencySetKind) -> Self {
353        Self {
354            set,
355            kind: DependencyKind::from(&d),
356            dep: Box::into_raw(Box::new(DependencyWrapper::String(d))),
357        }
358    }
359
360    pub(crate) fn new_uri(d: dep::Dependency<Uri>) -> Self {
361        Self {
362            set: DependencySetKind::SrcUri,
363            kind: DependencyKind::from(&d),
364            dep: Box::into_raw(Box::new(DependencyWrapper::Uri(d))),
365        }
366    }
367}
368
369impl Hash for Dependency {
370    fn hash<H: Hasher>(&self, state: &mut H) {
371        self.deref().hash(state)
372    }
373}
374
375impl Ord for Dependency {
376    fn cmp(&self, other: &Self) -> Ordering {
377        self.deref().cmp(other.deref())
378    }
379}
380
381impl PartialOrd for Dependency {
382    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
383        Some(self.cmp(other))
384    }
385}
386
387impl PartialEq for Dependency {
388    fn eq(&self, other: &Self) -> bool {
389        self.deref().eq(other.deref())
390    }
391}
392
393impl Eq for Dependency {}
394
395impl Deref for Dependency {
396    type Target = DependencyWrapper;
397
398    fn deref(&self) -> &Self::Target {
399        try_ref_from_ptr!(self.dep)
400    }
401}
402
403impl DerefMut for Dependency {
404    fn deref_mut(&mut self) -> &mut Self::Target {
405        try_mut_from_ptr!(self.dep)
406    }
407}
408
409impl fmt::Display for Dependency {
410    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
411        write!(f, "{}", self.deref())
412    }
413}
414
415/// Opaque wrapper for pkgcraft::dep::IntoIterFlatten<T>.
416#[derive(Debug)]
417pub enum DependencyIntoIterFlatten {
418    Dep(dep::IntoIterFlatten<Dep>),
419    String(dep::IntoIterFlatten<String>),
420    Uri(dep::IntoIterFlatten<Uri>),
421}
422
423impl Iterator for DependencyIntoIterFlatten {
424    type Item = *mut c_void;
425
426    fn next(&mut self) -> Option<Self::Item> {
427        match self {
428            Self::Dep(iter) => iter
429                .next()
430                .map(|x| Box::into_raw(Box::new(x)) as *mut c_void),
431            Self::String(iter) => iter
432                .next()
433                .map(|x| try_ptr_from_str!(x.as_str()) as *mut c_void),
434            Self::Uri(iter) => iter
435                .next()
436                .map(|x| Box::into_raw(Box::new(x)) as *mut c_void),
437        }
438    }
439}
440
441/// Opaque wrapper for pkgcraft::dep::IntoIterRecursive<T>.
442#[derive(Debug)]
443pub enum DependencyIntoIterRecursive {
444    Dep(DependencySetKind, dep::IntoIterRecursive<Dep>),
445    String(DependencySetKind, dep::IntoIterRecursive<String>),
446    Uri(DependencySetKind, dep::IntoIterRecursive<Uri>),
447}
448
449impl Iterator for DependencyIntoIterRecursive {
450    type Item = Dependency;
451
452    fn next(&mut self) -> Option<Self::Item> {
453        match self {
454            Self::Dep(_, iter) => iter.next().map(Dependency::new_dep),
455            Self::String(set, iter) => iter.next().map(|d| Dependency::new_string(d, *set)),
456            Self::Uri(_, iter) => iter.next().map(Dependency::new_uri),
457        }
458    }
459}
460
461/// Opaque wrapper for pkgcraft::dep::IntoIterConditionals<T>.
462#[derive(Debug)]
463pub enum DependencyIntoIterConditionals {
464    Dep(dep::IntoIterConditionals<Dep>),
465    String(dep::IntoIterConditionals<String>),
466    Uri(dep::IntoIterConditionals<Uri>),
467}
468
469impl Iterator for DependencyIntoIterConditionals {
470    type Item = dep::UseDep;
471
472    fn next(&mut self) -> Option<Self::Item> {
473        match self {
474            Self::Dep(iter) => iter.next(),
475            Self::String(iter) => iter.next(),
476            Self::Uri(iter) => iter.next(),
477        }
478    }
479}
480
481/// Create a new, empty DependencySet.
482///
483/// # Safety
484/// The argument must be a valid DependencySetKind.
485#[no_mangle]
486pub unsafe extern "C" fn pkgcraft_dependency_set_new(
487    kind: DependencySetKind,
488) -> *mut DependencySet {
489    use DependencySetKind::*;
490    let set = match kind {
491        Package => DependencySet::new_dep(Default::default()),
492        SrcUri => DependencySet::new_uri(Default::default()),
493        _ => DependencySet::new_string(Default::default(), kind),
494    };
495
496    Box::into_raw(Box::new(set))
497}
498
499/// Create a DependencySet from an array of Dependency objects.
500///
501/// Returns NULL on error.
502///
503/// # Safety
504/// The argument should be an array of similarly-typed Dependency objects.
505#[no_mangle]
506pub unsafe extern "C" fn pkgcraft_dependency_set_from_iter(
507    deps: *mut *mut Dependency,
508    len: usize,
509    kind: DependencySetKind,
510) -> *mut DependencySet {
511    ffi_catch_panic! {
512        let deps = unsafe { slice::from_raw_parts(deps, len) };
513        let deps = deps.iter().map(|p| try_ref_from_ptr!(p));
514        let (mut deps_dep, mut deps_string, mut deps_uri) = (vec![], vec![], vec![]);
515
516        for d in deps {
517            if d.set != kind {
518                set_error_and_panic!(
519                    Error::new(format!("Dependency kind {:?} doesn't match: {kind:?}", d.set))
520                );
521            }
522
523            match d.deref() {
524                DependencyWrapper::Dep(d) => deps_dep.push(d.clone()),
525                DependencyWrapper::String(d) => deps_string.push(d.clone()),
526                DependencyWrapper::Uri(d) => deps_uri.push(d.clone()),
527            }
528        }
529
530        use DependencySetKind::*;
531        let dep = match kind {
532            Package => DependencySet::new_dep(deps_dep.into_iter().collect()),
533            SrcUri => DependencySet::new_uri(deps_uri.into_iter().collect()),
534            _ => DependencySet::new_string(deps_string.into_iter().collect(), kind),
535        };
536
537        Box::into_raw(Box::new(dep))
538    }
539}
540
541/// Parse a string into a specified DependencySet type.
542///
543/// Returns NULL on error.
544///
545/// # Safety
546/// The argument should be a UTF-8 string.
547#[no_mangle]
548pub unsafe extern "C" fn pkgcraft_dependency_set_parse(
549    s: *const c_char,
550    eapi: *const Eapi,
551    kind: DependencySetKind,
552) -> *mut DependencySet {
553    ffi_catch_panic! {
554        let s = try_str_from_ptr!(s);
555        let eapi = eapi_or_default!(eapi);
556
557        use DependencySetKind::*;
558        let depset = match kind {
559            Package => {
560                let opt_dep = unwrap_or_panic!(dep::DependencySet::package(s, eapi));
561                DependencySet::new_dep(opt_dep)
562            },
563            SrcUri => {
564                let opt_dep = unwrap_or_panic!(dep::DependencySet::src_uri(s));
565                DependencySet::new_uri(opt_dep)
566            },
567            License => {
568                let opt_dep = unwrap_or_panic!(dep::DependencySet::license(s));
569                DependencySet::new_string(opt_dep, kind)
570            },
571            Properties => {
572                let opt_dep = unwrap_or_panic!(dep::DependencySet::properties(s));
573                DependencySet::new_string(opt_dep, kind)
574            },
575            RequiredUse => {
576                let opt_dep = unwrap_or_panic!(dep::DependencySet::required_use(s));
577                DependencySet::new_string(opt_dep, kind)
578            },
579            Restrict => {
580                let opt_dep = unwrap_or_panic!(dep::DependencySet::restrict(s));
581                DependencySet::new_string(opt_dep, kind)
582            },
583        };
584
585        Box::into_raw(Box::new(depset))
586    }
587}
588
589/// Parse a string into a specified Dependency type.
590///
591/// Returns NULL on error.
592///
593/// # Safety
594/// The argument should be a UTF-8 string.
595#[no_mangle]
596pub unsafe extern "C" fn pkgcraft_dependency_parse(
597    s: *const c_char,
598    eapi: *const Eapi,
599    kind: DependencySetKind,
600) -> *mut Dependency {
601    ffi_catch_panic! {
602        let s = try_str_from_ptr!(s);
603        let eapi = eapi_or_default!(eapi);
604
605        use DependencySetKind::*;
606        let dep = match kind {
607            Package => {
608                let dep = unwrap_or_panic!(dep::Dependency::package(s, eapi));
609                Dependency::new_dep(dep)
610            },
611            SrcUri => {
612                let dep = unwrap_or_panic!(dep::Dependency::src_uri(s));
613                Dependency::new_uri(dep)
614            },
615            License => {
616                let dep = unwrap_or_panic!(dep::Dependency::license(s));
617                Dependency::new_string(dep, kind)
618            },
619            Properties => {
620                let dep = unwrap_or_panic!(dep::Dependency::properties(s));
621                Dependency::new_string(dep, kind)
622            },
623            RequiredUse => {
624                let dep = unwrap_or_panic!(dep::Dependency::required_use(s));
625                Dependency::new_string(dep, kind)
626            },
627            Restrict => {
628                let dep = unwrap_or_panic!(dep::Dependency::restrict(s));
629                Dependency::new_string(dep, kind)
630            },
631        };
632
633        Box::into_raw(Box::new(dep))
634    }
635}
636
637/// Create a Dependency from a Dep.
638///
639/// # Safety
640/// The argument must be valid Dep pointer.
641#[no_mangle]
642pub unsafe extern "C" fn pkgcraft_dependency_from_dep(d: *mut Dep) -> *mut Dependency {
643    let d = try_ref_from_ptr!(d);
644    let dep = Dependency::new_dep(dep::Dependency::Enabled(d.clone()));
645    Box::into_raw(Box::new(dep))
646}
647
648/// Evaluate a DependencySet.
649///
650/// # Safety
651/// The argument must be a valid DependencySet pointer.
652#[no_mangle]
653pub unsafe extern "C" fn pkgcraft_dependency_set_evaluate(
654    d: *mut DependencySet,
655    options: *mut *mut c_char,
656    len: usize,
657) -> *mut DependencySet {
658    let dep = try_ref_from_ptr!(d);
659    let options = unsafe { slice::from_raw_parts(options, len) };
660    let options = options.iter().map(|p| try_str_from_ptr!(p)).collect();
661
662    use DependencySetWrapper::*;
663    let evaluated = match dep.deref() {
664        Dep(d) => Dep(d.evaluate(&options).into_owned()),
665        String(d) => String(d.evaluate(&options).into_owned()),
666        Uri(d) => Uri(d.evaluate(&options).into_owned()),
667    };
668
669    let dep = DependencySet {
670        set: dep.set,
671        dep: Box::into_raw(Box::new(evaluated)),
672    };
673
674    Box::into_raw(Box::new(dep))
675}
676
677/// Forcibly evaluate a DependencySet.
678///
679/// # Safety
680/// The argument must be a valid DependencySet pointer.
681#[no_mangle]
682pub unsafe extern "C" fn pkgcraft_dependency_set_evaluate_force(
683    d: *mut DependencySet,
684    force: bool,
685) -> *mut DependencySet {
686    let dep = try_ref_from_ptr!(d);
687
688    use DependencySetWrapper::*;
689    let evaluated = match dep.deref() {
690        Dep(d) => Dep(d.evaluate_force(force).into_owned()),
691        String(d) => String(d.evaluate_force(force).into_owned()),
692        Uri(d) => Uri(d.evaluate_force(force).into_owned()),
693    };
694
695    let dep = DependencySet {
696        set: dep.set,
697        dep: Box::into_raw(Box::new(evaluated)),
698    };
699
700    Box::into_raw(Box::new(dep))
701}
702
703/// Returns true if two DependencySets have no elements in common.
704///
705/// # Safety
706/// The arguments must be a valid DependencySet pointers.
707#[no_mangle]
708pub unsafe extern "C" fn pkgcraft_dependency_set_is_disjoint(
709    d1: *mut DependencySet,
710    d2: *mut DependencySet,
711) -> bool {
712    let d1 = try_deref_from_ptr!(d1);
713    let d2 = try_deref_from_ptr!(d2);
714
715    use DependencySetWrapper::*;
716    match (d1, d2) {
717        (Dep(d1), Dep(d2)) => d1.is_disjoint(d2),
718        (String(d1), String(d2)) => d1.is_disjoint(d2),
719        (Uri(d1), Uri(d2)) => d1.is_disjoint(d2),
720        _ => true,
721    }
722}
723
724/// Returns true if a DependencySet is empty.
725///
726/// # Safety
727/// The argument must be a valid DependencySet pointer.
728#[no_mangle]
729pub unsafe extern "C" fn pkgcraft_dependency_set_is_empty(d: *mut DependencySet) -> bool {
730    let deps = try_deref_from_ptr!(d);
731
732    match deps {
733        DependencySetWrapper::Dep(d) => d.is_empty(),
734        DependencySetWrapper::String(d) => d.is_empty(),
735        DependencySetWrapper::Uri(d) => d.is_empty(),
736    }
737}
738
739/// Returns true if all the elements of the first DependencySet are contained in the second.
740///
741/// # Safety
742/// The arguments must be a valid DependencySet pointers.
743#[no_mangle]
744pub unsafe extern "C" fn pkgcraft_dependency_set_is_subset(
745    d1: *mut DependencySet,
746    d2: *mut DependencySet,
747) -> bool {
748    let d1 = try_deref_from_ptr!(d1);
749    let d2 = try_deref_from_ptr!(d2);
750
751    use DependencySetWrapper::*;
752    match (d1, d2) {
753        (Dep(d1), Dep(d2)) => d1.is_subset(d2),
754        (String(d1), String(d2)) => d1.is_subset(d2),
755        (Uri(d1), Uri(d2)) => d1.is_subset(d2),
756        _ => false,
757    }
758}
759
760/// Returns the Dependency element for a given index.
761///
762/// Returns NULL on index nonexistence.
763///
764/// # Safety
765/// The argument must be a valid DependencySet pointer.
766#[no_mangle]
767pub unsafe extern "C" fn pkgcraft_dependency_set_get_index(
768    d: *mut DependencySet,
769    index: usize,
770) -> *mut Dependency {
771    ffi_catch_panic! {
772        let set = try_ref_from_ptr!(d);
773        let err = || Error::new(format!("failed getting DependencySet index: {index}"));
774
775        use DependencySetWrapper::*;
776        let dep = match set.deref() {
777            Dep(deps) => {
778                deps.get_index(index)
779                    .ok_or_else(err)
780                    .map(|d| Dependency::new_dep(d.clone()))
781            }
782            String(deps) => {
783                deps.get_index(index)
784                    .ok_or_else(err)
785                    .map(|d| Dependency::new_string(d.clone(), set.set))
786            }
787            Uri(deps) => {
788                deps.get_index(index)
789                    .ok_or_else(err)
790                    .map(|d| Dependency::new_uri(d.clone()))
791            }
792        };
793
794        Box::into_raw(Box::new(unwrap_or_panic!(dep)))
795    }
796}
797
798/// Sort a DependencySet.
799///
800/// # Safety
801/// The argument must be a valid DependencySet pointer.
802#[no_mangle]
803pub unsafe extern "C" fn pkgcraft_dependency_set_sort(d: *mut DependencySet) {
804    let set = try_mut_from_ptr!(d);
805
806    use DependencySetWrapper::*;
807    match set.deref_mut() {
808        Dep(deps) => deps.sort(),
809        String(deps) => deps.sort(),
810        Uri(deps) => deps.sort(),
811    }
812}
813
814/// Recursively sort a DependencySet.
815///
816/// # Safety
817/// The argument must be a valid DependencySet pointer.
818#[no_mangle]
819pub unsafe extern "C" fn pkgcraft_dependency_set_sort_recursive(d: *mut DependencySet) {
820    let set = try_mut_from_ptr!(d);
821
822    use DependencySetWrapper::*;
823    match set.deref_mut() {
824        Dep(deps) => deps.sort_recursive(),
825        String(deps) => deps.sort_recursive(),
826        Uri(deps) => deps.sort_recursive(),
827    }
828}
829
830/// Clone a DependencySet.
831///
832/// # Safety
833/// The argument must be a valid DependencySet pointer.
834#[no_mangle]
835pub unsafe extern "C" fn pkgcraft_dependency_set_clone(
836    d: *mut DependencySet,
837) -> *mut DependencySet {
838    let set = try_ref_from_ptr!(d);
839    Box::into_raw(Box::new(set.clone()))
840}
841
842/// Insert a Dependency into a DependencySet.
843///
844/// Returns false if an equivalent value already exists, otherwise true.
845///
846/// # Safety
847/// The arguments must be valid DependencySet and Dependency pointers.
848#[no_mangle]
849pub unsafe extern "C" fn pkgcraft_dependency_set_insert(
850    d: *mut DependencySet,
851    value: *mut Dependency,
852) -> bool {
853    let set = try_mut_from_ptr!(d);
854    let spec = try_deref_from_ptr!(value);
855
856    match (set.deref_mut(), spec.clone()) {
857        (DependencySetWrapper::Dep(deps), DependencyWrapper::Dep(dep)) => deps.insert(dep),
858        (DependencySetWrapper::String(deps), DependencyWrapper::String(dep)) => deps.insert(dep),
859        (DependencySetWrapper::Uri(deps), DependencyWrapper::Uri(dep)) => deps.insert(dep),
860        _ => panic!("invalid DependencySet and Dependency type combination"),
861    }
862}
863
864/// Remove the last value from a DependencySet.
865///
866/// Returns NULL on nonexistence.
867///
868/// # Safety
869/// The argument must be a valid DependencySet pointer.
870#[no_mangle]
871pub unsafe extern "C" fn pkgcraft_dependency_set_pop(d: *mut DependencySet) -> *mut Dependency {
872    let set = try_mut_from_ptr!(d);
873
874    use DependencySetWrapper::*;
875    let dep = match set.deref_mut() {
876        Dep(deps) => deps.pop().map(Dependency::new_dep),
877        String(deps) => deps.pop().map(|d| Dependency::new_string(d, set.set)),
878        Uri(deps) => deps.pop().map(Dependency::new_uri),
879    };
880
881    dep.map(boxed).unwrap_or(ptr::null_mut())
882}
883
884/// Replace a Dependency for a given index in a DependencySet, returning the replaced value.
885///
886/// Returns NULL on index nonexistence or if the DependencySet already contains the given Dependency.
887///
888/// # Safety
889/// The arguments must be valid DependencySet and Dependency pointers.
890#[no_mangle]
891pub unsafe extern "C" fn pkgcraft_dependency_set_replace_index(
892    d: *mut DependencySet,
893    index: usize,
894    value: *mut Dependency,
895) -> *mut Dependency {
896    let set = try_mut_from_ptr!(d);
897    let spec = try_deref_from_ptr!(value);
898
899    let dep = match (set.deref_mut(), spec) {
900        (DependencySetWrapper::Dep(deps), DependencyWrapper::Dep(dep)) => deps
901            .shift_replace_index(index, dep.clone())
902            .map(Dependency::new_dep),
903        (DependencySetWrapper::String(deps), DependencyWrapper::String(dep)) => deps
904            .shift_replace_index(index, dep.clone())
905            .map(|d| Dependency::new_string(d, set.set)),
906        (DependencySetWrapper::Uri(deps), DependencyWrapper::Uri(dep)) => deps
907            .shift_replace_index(index, dep.clone())
908            .map(Dependency::new_uri),
909        _ => panic!("invalid DependencySet and Dependency type combination"),
910    };
911
912    dep.map(boxed).unwrap_or(ptr::null_mut())
913}
914
915/// Replace a Dependency with another Dependency in a DependencySet, returning the replaced value.
916///
917/// Returns NULL on nonexistence or if the DependencySet already contains the given Dependency.
918///
919/// # Safety
920/// The arguments must be valid DependencySet and Dependency pointers.
921#[no_mangle]
922pub unsafe extern "C" fn pkgcraft_dependency_set_replace(
923    d: *mut DependencySet,
924    key: *const Dependency,
925    value: *mut Dependency,
926) -> *mut Dependency {
927    let set = try_mut_from_ptr!(d);
928    let key = try_deref_from_ptr!(key);
929    let value = try_deref_from_ptr!(value);
930
931    let dep = match (set.deref_mut(), key, value) {
932        (DependencySetWrapper::Dep(deps), DependencyWrapper::Dep(k), DependencyWrapper::Dep(v)) => {
933            deps.shift_replace(k, v.clone()).map(Dependency::new_dep)
934        }
935        (
936            DependencySetWrapper::String(deps),
937            DependencyWrapper::String(k),
938            DependencyWrapper::String(v),
939        ) => deps
940            .shift_replace(k, v.clone())
941            .map(|d| Dependency::new_string(d, set.set)),
942        (DependencySetWrapper::Uri(deps), DependencyWrapper::Uri(k), DependencyWrapper::Uri(v)) => {
943            deps.shift_replace(k, v.clone()).map(Dependency::new_uri)
944        }
945        _ => panic!("invalid DependencySet and Dependency type combination"),
946    };
947
948    dep.map(boxed).unwrap_or(ptr::null_mut())
949}
950
951/// Perform a set operation on two DependencySets, assigning to the first.
952///
953/// Returns NULL on error.
954///
955/// # Safety
956/// The arguments must be valid DependencySet pointers.
957#[no_mangle]
958pub unsafe extern "C" fn pkgcraft_dependency_set_assign_op_set(
959    op: SetOp,
960    d1: *mut DependencySet,
961    d2: *mut DependencySet,
962) -> *mut DependencySet {
963    ffi_catch_panic! {
964        use SetOp::*;
965        let dep1 = try_mut_from_ptr!(d1);
966        let dep2 = try_ref_from_ptr!(d2);
967        match op {
968            And => *dep1 &= dep2,
969            Or => *dep1 |= dep2,
970            Xor => *dep1 ^= dep2,
971            Sub => *dep1 -= dep2,
972        }
973        d1
974    }
975}
976
977/// Perform a set operation on two DependencySets, creating a new set.
978///
979/// Returns NULL on error.
980///
981/// # Safety
982/// The arguments must be valid DependencySet pointers.
983#[no_mangle]
984pub unsafe extern "C" fn pkgcraft_dependency_set_op_set(
985    op: SetOp,
986    d1: *mut DependencySet,
987    d2: *mut DependencySet,
988) -> *mut DependencySet {
989    ffi_catch_panic! {
990        use SetOp::*;
991        let d1 = try_ref_from_ptr!(d1);
992        let d2 = try_ref_from_ptr!(d2);
993        let set = match op {
994            And => d1 & d2,
995            Or => d1 | d2,
996            Xor => d1 ^ d2,
997            Sub => d1 - d2,
998        };
999        Box::into_raw(Box::new(set))
1000    }
1001}
1002
1003/// Return the formatted string for a DependencySet object.
1004///
1005/// # Safety
1006/// The argument must be a valid DependencySet pointer.
1007#[no_mangle]
1008pub unsafe extern "C" fn pkgcraft_dependency_set_str(d: *mut DependencySet) -> *mut c_char {
1009    let deps = try_ref_from_ptr!(d);
1010    try_ptr_from_str!(deps.to_string())
1011}
1012
1013/// Determine if two DependencySets are equal.
1014///
1015/// # Safety
1016/// The arguments must be valid DependencySet pointers.
1017#[no_mangle]
1018pub unsafe extern "C" fn pkgcraft_dependency_set_eq(
1019    d1: *mut DependencySet,
1020    d2: *mut DependencySet,
1021) -> bool {
1022    let d1 = try_ref_from_ptr!(d1);
1023    let d2 = try_ref_from_ptr!(d2);
1024    d1.eq(d2)
1025}
1026
1027/// Determine if a DependencySet contains a given Dependency.
1028///
1029/// # Safety
1030/// The arguments must be valid DependencySet and Dependency pointers.
1031#[no_mangle]
1032pub unsafe extern "C" fn pkgcraft_dependency_set_contains_dependency(
1033    s: *mut DependencySet,
1034    d: *mut Dependency,
1035) -> bool {
1036    let s = try_deref_from_ptr!(s);
1037    let d = try_deref_from_ptr!(d);
1038
1039    match (s, d) {
1040        (DependencySetWrapper::Dep(s), DependencyWrapper::Dep(d)) => s.contains(d),
1041        (DependencySetWrapper::String(s), DependencyWrapper::String(d)) => s.contains(d),
1042        (DependencySetWrapper::Uri(s), DependencyWrapper::Uri(d)) => s.contains(d),
1043        _ => false,
1044    }
1045}
1046
1047/// Determine if a DependencySet contains a given raw string.
1048///
1049/// # Safety
1050/// The arguments must be valid pointers.
1051#[no_mangle]
1052pub unsafe extern "C" fn pkgcraft_dependency_set_contains_str(
1053    d: *mut DependencySet,
1054    s: *const c_char,
1055) -> bool {
1056    let d = try_deref_from_ptr!(d);
1057    let s = try_str_from_ptr!(s);
1058
1059    match d {
1060        DependencySetWrapper::Dep(d) => d.contains(s),
1061        DependencySetWrapper::String(d) => d.contains(s),
1062        DependencySetWrapper::Uri(d) => d.contains(s),
1063    }
1064}
1065
1066/// Determine if a DependencySet contains a given UseDep.
1067///
1068/// # Safety
1069/// The arguments must be valid pointers.
1070#[no_mangle]
1071pub unsafe extern "C" fn pkgcraft_dependency_set_contains_use_dep(
1072    d: *mut DependencySet,
1073    u: *mut use_dep::UseDep,
1074) -> bool {
1075    let d = try_deref_from_ptr!(d);
1076    let u = try_deref_from_ptr!(u);
1077
1078    match d {
1079        DependencySetWrapper::Dep(d) => d.contains(u),
1080        DependencySetWrapper::String(d) => d.contains(u),
1081        DependencySetWrapper::Uri(d) => d.contains(u),
1082    }
1083}
1084
1085/// Determine if a DependencySet contains a given Dep.
1086///
1087/// # Safety
1088/// The arguments must be valid pointers.
1089#[no_mangle]
1090pub unsafe extern "C" fn pkgcraft_dependency_set_contains_dep(
1091    d: *mut DependencySet,
1092    dep: *mut Dep,
1093) -> bool {
1094    let d = try_deref_from_ptr!(d);
1095    let dep = try_ref_from_ptr!(dep);
1096
1097    match d {
1098        DependencySetWrapper::Dep(d) => d.contains(dep),
1099        _ => false,
1100    }
1101}
1102
1103/// Determine if a DependencySet contains a given Uri.
1104///
1105/// # Safety
1106/// The arguments must be valid pointers.
1107#[no_mangle]
1108pub unsafe extern "C" fn pkgcraft_dependency_set_contains_uri(
1109    d: *mut DependencySet,
1110    uri: *mut Uri,
1111) -> bool {
1112    let d = try_deref_from_ptr!(d);
1113    let uri = try_ref_from_ptr!(uri);
1114
1115    match d {
1116        DependencySetWrapper::Uri(d) => d.contains(uri),
1117        _ => false,
1118    }
1119}
1120
1121/// Return the hash value for a DependencySet.
1122///
1123/// # Safety
1124/// The argument must be a valid DependencySet pointer.
1125#[no_mangle]
1126pub unsafe extern "C" fn pkgcraft_dependency_set_hash(d: *mut DependencySet) -> u64 {
1127    let deps = try_ref_from_ptr!(d);
1128    hash(deps)
1129}
1130
1131/// Return a DependencySet's length.
1132///
1133/// # Safety
1134/// The argument must be a valid DependencySet pointer.
1135#[no_mangle]
1136pub unsafe extern "C" fn pkgcraft_dependency_set_len(d: *mut DependencySet) -> usize {
1137    let deps = try_deref_from_ptr!(d);
1138    use DependencySetWrapper::*;
1139    match deps {
1140        Dep(d) => d.len(),
1141        String(d) => d.len(),
1142        Uri(d) => d.len(),
1143    }
1144}
1145
1146/// Return an iterator for a DependencySet.
1147///
1148/// # Safety
1149/// The argument must be a valid DependencySet pointer.
1150#[no_mangle]
1151pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter(
1152    d: *mut DependencySet,
1153) -> *mut DependencyIntoIter {
1154    let deps = try_ref_from_ptr!(d);
1155    let iter = match deps.deref().clone() {
1156        DependencySetWrapper::Dep(d) => DependencyIntoIter::Dep(deps.set, d.into_iter()),
1157        DependencySetWrapper::String(d) => DependencyIntoIter::String(deps.set, d.into_iter()),
1158        DependencySetWrapper::Uri(d) => DependencyIntoIter::Uri(deps.set, d.into_iter()),
1159    };
1160    Box::into_raw(Box::new(iter))
1161}
1162
1163/// Return the next object from a DependencySet iterator.
1164///
1165/// Returns NULL when the iterator is empty.
1166///
1167/// # Safety
1168/// The argument must be a valid DependencyIntoIter pointer.
1169#[no_mangle]
1170pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_next(
1171    i: *mut DependencyIntoIter,
1172) -> *mut Dependency {
1173    let iter = try_mut_from_ptr!(i);
1174    iter.next().map(boxed).unwrap_or(ptr::null_mut())
1175}
1176
1177/// Return the next object from the end of a DependencySet iterator.
1178///
1179/// Returns NULL when the iterator is empty.
1180///
1181/// # Safety
1182/// The argument must be a valid DependencyIntoIter pointer.
1183#[no_mangle]
1184pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_next_back(
1185    i: *mut DependencyIntoIter,
1186) -> *mut Dependency {
1187    let iter = try_mut_from_ptr!(i);
1188    iter.next_back().map(boxed).unwrap_or(ptr::null_mut())
1189}
1190
1191/// Free a DependencySet iterator.
1192///
1193/// # Safety
1194/// The argument must be a valid DependencyIntoIter pointer or NULL.
1195#[no_mangle]
1196pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_free(i: *mut DependencyIntoIter) {
1197    if !i.is_null() {
1198        unsafe { drop(Box::from_raw(i)) };
1199    }
1200}
1201
1202/// Evaluate a Dependency.
1203///
1204/// # Safety
1205/// The argument must be a valid Dependency pointer.
1206#[no_mangle]
1207pub unsafe extern "C" fn pkgcraft_dependency_evaluate(
1208    d: *mut Dependency,
1209    options: *mut *mut c_char,
1210    len: usize,
1211    deps_len: *mut usize,
1212) -> *mut *mut Dependency {
1213    let dep = try_ref_from_ptr!(d);
1214    let options = unsafe { slice::from_raw_parts(options, len) };
1215    let options = options.iter().map(|p| try_str_from_ptr!(p)).collect();
1216
1217    use DependencyWrapper::*;
1218    match dep.deref() {
1219        Dep(d) => {
1220            iter_to_array!(d.evaluate(&options).into_iter(), deps_len, |d| {
1221                Box::into_raw(Box::new(Dependency::new_dep(d.into_owned())))
1222            })
1223        }
1224        String(d) => {
1225            iter_to_array!(d.evaluate(&options).into_iter(), deps_len, |d| {
1226                Box::into_raw(Box::new(Dependency::new_string(d.into_owned(), dep.set)))
1227            })
1228        }
1229        Uri(d) => {
1230            iter_to_array!(d.evaluate(&options).into_iter(), deps_len, |d| {
1231                Box::into_raw(Box::new(Dependency::new_uri(d.into_owned())))
1232            })
1233        }
1234    }
1235}
1236
1237/// Forcibly evaluate a Dependency.
1238///
1239/// # Safety
1240/// The argument must be a valid Dependency pointer.
1241#[no_mangle]
1242pub unsafe extern "C" fn pkgcraft_dependency_evaluate_force(
1243    d: *mut Dependency,
1244    force: bool,
1245    deps_len: *mut usize,
1246) -> *mut *mut Dependency {
1247    let dep = try_ref_from_ptr!(d);
1248
1249    use DependencyWrapper::*;
1250    match dep.deref() {
1251        Dep(d) => {
1252            iter_to_array!(d.evaluate_force(force).into_iter(), deps_len, |d| {
1253                Box::into_raw(Box::new(Dependency::new_dep(d.into_owned())))
1254            })
1255        }
1256        String(d) => {
1257            iter_to_array!(d.evaluate_force(force).into_iter(), deps_len, |d| {
1258                Box::into_raw(Box::new(Dependency::new_string(d.into_owned(), dep.set)))
1259            })
1260        }
1261        Uri(d) => {
1262            iter_to_array!(d.evaluate_force(force).into_iter(), deps_len, |d| {
1263                Box::into_raw(Box::new(Dependency::new_uri(d.into_owned())))
1264            })
1265        }
1266    }
1267}
1268
1269/// Return the conditional for a Dependency.
1270///
1271/// Returns NULL if the Dependency variant isn't conditional.
1272///
1273/// # Safety
1274/// The argument must be a valid Dependency pointer.
1275#[no_mangle]
1276pub unsafe extern "C" fn pkgcraft_dependency_conditional(
1277    d: *mut Dependency,
1278) -> *mut use_dep::UseDep {
1279    let d = try_deref_from_ptr!(d);
1280
1281    use DependencyWrapper::*;
1282    let use_dep = match d {
1283        Dep(dep::Dependency::Conditional(u, _)) => Some(u.clone().into()),
1284        String(dep::Dependency::Conditional(u, _)) => Some(u.clone().into()),
1285        Uri(dep::Dependency::Conditional(u, _)) => Some(u.clone().into()),
1286        _ => None,
1287    };
1288
1289    use_dep.map(boxed).unwrap_or(ptr::null_mut())
1290}
1291
1292/// Compare two Dependencys returning -1, 0, or 1 if the first is less than, equal to, or greater
1293/// than the second, respectively.
1294///
1295/// # Safety
1296/// The arguments must be valid Dependency pointers.
1297#[no_mangle]
1298pub unsafe extern "C" fn pkgcraft_dependency_cmp(
1299    d1: *mut Dependency,
1300    d2: *mut Dependency,
1301) -> c_int {
1302    let d1 = try_ref_from_ptr!(d1);
1303    let d2 = try_ref_from_ptr!(d2);
1304
1305    match d1.cmp(d2) {
1306        Ordering::Less => -1,
1307        Ordering::Equal => 0,
1308        Ordering::Greater => 1,
1309    }
1310}
1311
1312/// Determine if a Dependency contains a given Dependency.
1313///
1314/// # Safety
1315/// The arguments must be valid Dependency pointers.
1316#[no_mangle]
1317pub unsafe extern "C" fn pkgcraft_dependency_contains_dependency(
1318    d1: *mut Dependency,
1319    d2: *mut Dependency,
1320) -> bool {
1321    let d1 = try_deref_from_ptr!(d1);
1322    let d2 = try_deref_from_ptr!(d2);
1323
1324    use DependencyWrapper::*;
1325    match (d1, d2) {
1326        (Dep(d1), Dep(d2)) => d1.contains(d2),
1327        (String(d1), String(d2)) => d1.contains(d2),
1328        (Uri(d1), Uri(d2)) => d1.contains(d2),
1329        _ => false,
1330    }
1331}
1332
1333/// Determine if a Dependency contains a given raw string.
1334///
1335/// # Safety
1336/// The arguments must be valid pointers.
1337#[no_mangle]
1338pub unsafe extern "C" fn pkgcraft_dependency_contains_str(
1339    d: *mut Dependency,
1340    s: *const c_char,
1341) -> bool {
1342    let d = try_deref_from_ptr!(d);
1343    let s = try_str_from_ptr!(s);
1344
1345    match d {
1346        DependencyWrapper::Dep(d) => d.contains(s),
1347        DependencyWrapper::String(d) => d.contains(s),
1348        DependencyWrapper::Uri(d) => d.contains(s),
1349    }
1350}
1351
1352/// Determine if a Dependency contains a given UseDep.
1353///
1354/// # Safety
1355/// The arguments must be valid pointers.
1356#[no_mangle]
1357pub unsafe extern "C" fn pkgcraft_dependency_contains_use_dep(
1358    d: *mut Dependency,
1359    u: *mut use_dep::UseDep,
1360) -> bool {
1361    let d = try_deref_from_ptr!(d);
1362    let u = try_deref_from_ptr!(u);
1363
1364    match d {
1365        DependencyWrapper::Dep(d) => d.contains(u),
1366        DependencyWrapper::String(d) => d.contains(u),
1367        DependencyWrapper::Uri(d) => d.contains(u),
1368    }
1369}
1370
1371/// Determine if a Dependency contains a given Dep.
1372///
1373/// # Safety
1374/// The arguments must be valid pointers.
1375#[no_mangle]
1376pub unsafe extern "C" fn pkgcraft_dependency_contains_dep(
1377    d: *mut Dependency,
1378    dep: *mut Dep,
1379) -> bool {
1380    let d = try_deref_from_ptr!(d);
1381    let dep = try_ref_from_ptr!(dep);
1382
1383    match d {
1384        DependencyWrapper::Dep(d) => d.contains(dep),
1385        _ => false,
1386    }
1387}
1388
1389/// Determine if a Dependency contains a given Uri.
1390///
1391/// # Safety
1392/// The arguments must be valid pointers.
1393#[no_mangle]
1394pub unsafe extern "C" fn pkgcraft_dependency_contains_uri(
1395    d: *mut Dependency,
1396    uri: *mut Uri,
1397) -> bool {
1398    let d = try_deref_from_ptr!(d);
1399    let uri = try_ref_from_ptr!(uri);
1400
1401    match d {
1402        DependencyWrapper::Uri(d) => d.contains(uri),
1403        _ => false,
1404    }
1405}
1406
1407/// Return the Dependency for a given index if it exists.
1408///
1409/// Returns NULL on index nonexistence.
1410///
1411/// # Safety
1412/// The argument must be a valid Dependency pointer.
1413#[no_mangle]
1414pub unsafe extern "C" fn pkgcraft_dependency_get_index(
1415    d: *mut Dependency,
1416    index: usize,
1417) -> *mut Dependency {
1418    ffi_catch_panic! {
1419        let dep = try_ref_from_ptr!(d);
1420        let err = || Error::new(format!("failed getting Dependency index: {index}"));
1421
1422        use DependencyWrapper::*;
1423        let dep = match dep.deref() {
1424            Dep(d) => {
1425                d.get_index(index)
1426                    .ok_or_else(err)
1427                    .map(|d| Dependency::new_dep(d.clone()))
1428            }
1429            String(d) => {
1430                d.get_index(index)
1431                    .ok_or_else(err)
1432                    .map(|d| Dependency::new_string(d.clone(), dep.set))
1433            }
1434            Uri(d) => {
1435                d.get_index(index)
1436                    .ok_or_else(err)
1437                    .map(|d| Dependency::new_uri(d.clone()))
1438            }
1439        };
1440
1441        Box::into_raw(Box::new(unwrap_or_panic!(dep)))
1442    }
1443}
1444
1445/// Return the hash value for a Dependency.
1446///
1447/// # Safety
1448/// The argument must be a valid Dependency pointer.
1449#[no_mangle]
1450pub unsafe extern "C" fn pkgcraft_dependency_hash(d: *mut Dependency) -> u64 {
1451    let deps = try_ref_from_ptr!(d);
1452    hash(deps)
1453}
1454
1455/// Return a Dependency's length.
1456///
1457/// # Safety
1458/// The argument must be a valid Dependency pointer.
1459#[no_mangle]
1460pub unsafe extern "C" fn pkgcraft_dependency_len(d: *mut Dependency) -> usize {
1461    let deps = try_deref_from_ptr!(d);
1462    use DependencyWrapper::*;
1463    match deps {
1464        Dep(d) => d.len(),
1465        String(d) => d.len(),
1466        Uri(d) => d.len(),
1467    }
1468}
1469
1470/// Recursively sort a Dependency.
1471///
1472/// # Safety
1473/// The argument must be a valid Dependency pointer.
1474#[no_mangle]
1475pub unsafe extern "C" fn pkgcraft_dependency_sort(d: *mut Dependency) {
1476    let dep = try_mut_from_ptr!(d);
1477
1478    use DependencyWrapper::*;
1479    match dep.deref_mut() {
1480        Dep(d) => d.sort(),
1481        String(d) => d.sort(),
1482        Uri(d) => d.sort(),
1483    }
1484}
1485
1486/// Return the formatted string for a Dependency object.
1487///
1488/// # Safety
1489/// The argument must be a valid Dependency pointer.
1490#[no_mangle]
1491pub unsafe extern "C" fn pkgcraft_dependency_str(d: *mut Dependency) -> *mut c_char {
1492    let deps = try_ref_from_ptr!(d);
1493    try_ptr_from_str!(deps.to_string())
1494}
1495
1496/// Free a Dependency object.
1497///
1498/// # Safety
1499/// The argument must be a Dependency pointer or NULL.
1500#[no_mangle]
1501pub unsafe extern "C" fn pkgcraft_dependency_free(r: *mut Dependency) {
1502    if !r.is_null() {
1503        unsafe { drop(Box::from_raw(r)) };
1504    }
1505}
1506
1507/// Return an iterator for a Dependency.
1508///
1509/// # Safety
1510/// The argument must be a valid Dependency pointer.
1511#[no_mangle]
1512pub unsafe extern "C" fn pkgcraft_dependency_into_iter(
1513    d: *mut Dependency,
1514) -> *mut DependencyIntoIter {
1515    let deps = try_ref_from_ptr!(d);
1516    let iter = match deps.deref().clone() {
1517        DependencyWrapper::Dep(d) => DependencyIntoIter::Dep(deps.set, d.into_iter()),
1518        DependencyWrapper::String(d) => DependencyIntoIter::String(deps.set, d.into_iter()),
1519        DependencyWrapper::Uri(d) => DependencyIntoIter::Uri(deps.set, d.into_iter()),
1520    };
1521    Box::into_raw(Box::new(iter))
1522}
1523
1524/// Return a flatten iterator for a Dependency.
1525///
1526/// # Safety
1527/// The argument must be a valid Dependency pointer.
1528#[no_mangle]
1529pub unsafe extern "C" fn pkgcraft_dependency_into_iter_flatten(
1530    d: *mut Dependency,
1531) -> *mut DependencyIntoIterFlatten {
1532    let dep = try_deref_from_ptr!(d);
1533    let iter = match dep.clone() {
1534        DependencyWrapper::Dep(d) => DependencyIntoIterFlatten::Dep(d.into_iter_flatten()),
1535        DependencyWrapper::String(d) => DependencyIntoIterFlatten::String(d.into_iter_flatten()),
1536        DependencyWrapper::Uri(d) => DependencyIntoIterFlatten::Uri(d.into_iter_flatten()),
1537    };
1538    Box::into_raw(Box::new(iter))
1539}
1540
1541/// Return a flatten iterator for a DependencySet.
1542///
1543/// # Safety
1544/// The argument must be a valid DependencySet pointer.
1545#[no_mangle]
1546pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_flatten(
1547    d: *mut DependencySet,
1548) -> *mut DependencyIntoIterFlatten {
1549    let deps = try_deref_from_ptr!(d);
1550    let iter = match deps.clone() {
1551        DependencySetWrapper::Dep(d) => DependencyIntoIterFlatten::Dep(d.into_iter_flatten()),
1552        DependencySetWrapper::String(d) => DependencyIntoIterFlatten::String(d.into_iter_flatten()),
1553        DependencySetWrapper::Uri(d) => DependencyIntoIterFlatten::Uri(d.into_iter_flatten()),
1554    };
1555    Box::into_raw(Box::new(iter))
1556}
1557
1558/// Return the next object from a flatten iterator.
1559///
1560/// Returns NULL when the iterator is empty.
1561///
1562/// # Safety
1563/// The argument must be a valid DependencyIntoIterFlatten pointer.
1564#[no_mangle]
1565pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_flatten_next(
1566    i: *mut DependencyIntoIterFlatten,
1567) -> *mut c_void {
1568    let iter = try_mut_from_ptr!(i);
1569    iter.next().unwrap_or(ptr::null_mut())
1570}
1571
1572/// Free a flatten iterator.
1573///
1574/// # Safety
1575/// The argument must be a valid DependencyIntoIterFlatten pointer or NULL.
1576#[no_mangle]
1577pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_flatten_free(
1578    i: *mut DependencyIntoIterFlatten,
1579) {
1580    if !i.is_null() {
1581        unsafe { drop(Box::from_raw(i)) };
1582    }
1583}
1584
1585/// Return a recursive iterator for a Dependency.
1586///
1587/// # Safety
1588/// The argument must be a valid Dependency pointer.
1589#[no_mangle]
1590pub unsafe extern "C" fn pkgcraft_dependency_into_iter_recursive(
1591    d: *mut Dependency,
1592) -> *mut DependencyIntoIterRecursive {
1593    let dep = try_ref_from_ptr!(d);
1594    let iter = match dep.deref().clone() {
1595        DependencyWrapper::Dep(d) => {
1596            DependencyIntoIterRecursive::Dep(dep.set, d.into_iter_recursive())
1597        }
1598        DependencyWrapper::String(d) => {
1599            DependencyIntoIterRecursive::String(dep.set, d.into_iter_recursive())
1600        }
1601        DependencyWrapper::Uri(d) => {
1602            DependencyIntoIterRecursive::Uri(dep.set, d.into_iter_recursive())
1603        }
1604    };
1605    Box::into_raw(Box::new(iter))
1606}
1607
1608/// Return a recursive iterator for a DependencySet.
1609///
1610/// # Safety
1611/// The argument must be a valid DependencySet pointer.
1612#[no_mangle]
1613pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_recursive(
1614    d: *mut DependencySet,
1615) -> *mut DependencyIntoIterRecursive {
1616    let deps = try_ref_from_ptr!(d);
1617    let iter = match deps.deref().clone() {
1618        DependencySetWrapper::Dep(d) => {
1619            DependencyIntoIterRecursive::Dep(deps.set, d.into_iter_recursive())
1620        }
1621        DependencySetWrapper::String(d) => {
1622            DependencyIntoIterRecursive::String(deps.set, d.into_iter_recursive())
1623        }
1624        DependencySetWrapper::Uri(d) => {
1625            DependencyIntoIterRecursive::Uri(deps.set, d.into_iter_recursive())
1626        }
1627    };
1628    Box::into_raw(Box::new(iter))
1629}
1630
1631/// Return the next object from a recursive iterator.
1632///
1633/// Returns NULL when the iterator is empty.
1634///
1635/// # Safety
1636/// The argument must be a valid DependencyIntoIterRecursive pointer.
1637#[no_mangle]
1638pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_recursive_next(
1639    i: *mut DependencyIntoIterRecursive,
1640) -> *mut Dependency {
1641    let iter = try_mut_from_ptr!(i);
1642    iter.next().map(boxed).unwrap_or(ptr::null_mut())
1643}
1644
1645/// Free a recursive iterator.
1646///
1647/// # Safety
1648/// The argument must be a valid DependencyIntoIterRecursive pointer or NULL.
1649#[no_mangle]
1650pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_recursive_free(
1651    i: *mut DependencyIntoIterRecursive,
1652) {
1653    if !i.is_null() {
1654        unsafe { drop(Box::from_raw(i)) };
1655    }
1656}
1657
1658/// Return a conditionals iterator for a Dependency.
1659///
1660/// # Safety
1661/// The argument must be a valid Dependency pointer.
1662#[no_mangle]
1663pub unsafe extern "C" fn pkgcraft_dependency_into_iter_conditionals(
1664    d: *mut Dependency,
1665) -> *mut DependencyIntoIterConditionals {
1666    let dep = try_ref_from_ptr!(d);
1667    let iter = match dep.deref().clone() {
1668        DependencyWrapper::Dep(d) => {
1669            DependencyIntoIterConditionals::Dep(d.into_iter_conditionals())
1670        }
1671        DependencyWrapper::String(d) => {
1672            DependencyIntoIterConditionals::String(d.into_iter_conditionals())
1673        }
1674        DependencyWrapper::Uri(d) => {
1675            DependencyIntoIterConditionals::Uri(d.into_iter_conditionals())
1676        }
1677    };
1678    Box::into_raw(Box::new(iter))
1679}
1680
1681/// Return a conditionals iterator for a DependencySet.
1682///
1683/// # Safety
1684/// The argument must be a valid DependencySet pointer.
1685#[no_mangle]
1686pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_conditionals(
1687    d: *mut DependencySet,
1688) -> *mut DependencyIntoIterConditionals {
1689    let deps = try_ref_from_ptr!(d);
1690    let iter = match deps.deref().clone() {
1691        DependencySetWrapper::Dep(d) => {
1692            DependencyIntoIterConditionals::Dep(d.into_iter_conditionals())
1693        }
1694        DependencySetWrapper::String(d) => {
1695            DependencyIntoIterConditionals::String(d.into_iter_conditionals())
1696        }
1697        DependencySetWrapper::Uri(d) => {
1698            DependencyIntoIterConditionals::Uri(d.into_iter_conditionals())
1699        }
1700    };
1701    Box::into_raw(Box::new(iter))
1702}
1703
1704/// Return the next object from a conditionals iterator.
1705///
1706/// Returns NULL when the iterator is empty.
1707///
1708/// # Safety
1709/// The argument must be a valid DependencyIntoIterConditionals pointer.
1710#[no_mangle]
1711pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_conditionals_next(
1712    i: *mut DependencyIntoIterConditionals,
1713) -> *mut use_dep::UseDep {
1714    let iter = try_mut_from_ptr!(i);
1715    iter.next()
1716        .map(|x| boxed(x.into()))
1717        .unwrap_or(ptr::null_mut())
1718}
1719
1720/// Free a conditionals iterator.
1721///
1722/// # Safety
1723/// The argument must be a valid DependencyIntoIterConditionals pointer or NULL.
1724#[no_mangle]
1725pub unsafe extern "C" fn pkgcraft_dependency_set_into_iter_conditionals_free(
1726    i: *mut DependencyIntoIterConditionals,
1727) {
1728    if !i.is_null() {
1729        unsafe { drop(Box::from_raw(i)) };
1730    }
1731}
1732
1733/// Free a DependencySet.
1734///
1735/// # Safety
1736/// The argument must be a DependencySet pointer or NULL.
1737#[no_mangle]
1738pub unsafe extern "C" fn pkgcraft_dependency_set_free(d: *mut DependencySet) {
1739    if !d.is_null() {
1740        unsafe { drop(Box::from_raw(d)) };
1741    }
1742}