pkgcraft/
pkg.rs

1use std::cmp::Ordering;
2use std::ffi::{c_char, c_int};
3
4use pkgcraft::dep::{Cpn, Cpv, Dep, Version};
5use pkgcraft::eapi::Eapi;
6use pkgcraft::pkg::{Package, Pkg, RepoPackage};
7use pkgcraft::repo::Repo;
8use pkgcraft::restrict::{Restrict, Restriction};
9use pkgcraft::traits::Intersects;
10use pkgcraft::utils::hash;
11
12use crate::macros::*;
13
14pub mod ebuild;
15
16#[repr(C)]
17pub enum PkgFormat {
18    Configured,
19    Ebuild,
20    Fake,
21}
22
23impl From<&Pkg<'_>> for PkgFormat {
24    fn from(pkg: &Pkg) -> Self {
25        match pkg {
26            Pkg::Configured(_, _) => Self::Configured,
27            Pkg::Ebuild(_, _) => Self::Ebuild,
28            Pkg::Fake(_, _) => Self::Fake,
29        }
30    }
31}
32
33/// Return a package's format.
34///
35/// # Safety
36/// The argument must be a non-null Pkg pointer.
37#[no_mangle]
38pub unsafe extern "C" fn pkgcraft_pkg_format(p: *mut Pkg) -> PkgFormat {
39    let pkg = try_ref_from_ptr!(p);
40    pkg.into()
41}
42
43/// Return a package's CPV.
44///
45/// # Safety
46/// The argument must be a non-null Pkg pointer.
47#[no_mangle]
48pub unsafe extern "C" fn pkgcraft_pkg_cpv(p: *mut Pkg) -> *mut Cpv {
49    let pkg = try_ref_from_ptr!(p);
50    Box::into_raw(Box::new(pkg.cpv().clone()))
51}
52
53/// Return a package's repo.
54///
55/// # Safety
56/// The argument must be a non-null Pkg pointer.
57#[no_mangle]
58pub unsafe extern "C" fn pkgcraft_pkg_repo(p: *mut Pkg) -> *const Repo {
59    let pkg = try_ref_from_ptr!(p);
60    pkg.repo()
61}
62
63/// Return a package's EAPI.
64///
65/// # Safety
66/// The argument must be a non-null Pkg pointer.
67#[no_mangle]
68pub unsafe extern "C" fn pkgcraft_pkg_eapi(p: *mut Pkg) -> *const Eapi {
69    let pkg = try_ref_from_ptr!(p);
70    pkg.eapi()
71}
72
73/// Return a package's version.
74///
75/// # Safety
76/// The argument must be a non-null Pkg pointer.
77#[no_mangle]
78pub unsafe extern "C" fn pkgcraft_pkg_version(p: *mut Pkg) -> *mut Version {
79    let pkg = try_ref_from_ptr!(p);
80    Box::into_raw(Box::new(pkg.version().clone()))
81}
82
83/// Compare two packages returning -1, 0, or 1 if the first package is less than, equal to, or
84/// greater than the second package, respectively.
85///
86/// # Safety
87/// The arguments must be non-null Pkg pointers.
88#[no_mangle]
89pub unsafe extern "C" fn pkgcraft_pkg_cmp<'a>(p1: *mut Pkg<'a>, p2: *mut Pkg<'a>) -> c_int {
90    let pkg1 = try_ref_from_ptr!(p1);
91    let pkg2 = try_ref_from_ptr!(p2);
92
93    match pkg1.cmp(pkg2) {
94        Ordering::Less => -1,
95        Ordering::Equal => 0,
96        Ordering::Greater => 1,
97    }
98}
99
100/// Determine if a package intersects with a package dependency.
101///
102/// # Safety
103/// The arguments should be non-null pointers.
104#[no_mangle]
105pub unsafe extern "C" fn pkgcraft_pkg_intersects_dep(p: *mut Pkg, d: *mut Dep) -> bool {
106    let pkg = try_ref_from_ptr!(p);
107    let dep = try_ref_from_ptr!(d);
108    pkg.intersects(dep)
109}
110
111/// Determine if a package intersects with a Cpv.
112///
113/// # Safety
114/// The arguments should be non-null pointers.
115#[no_mangle]
116pub unsafe extern "C" fn pkgcraft_pkg_intersects_cpv(p: *mut Pkg, c: *mut Cpv) -> bool {
117    let pkg = try_ref_from_ptr!(p);
118    let cpv = try_ref_from_ptr!(c);
119    pkg.intersects(cpv)
120}
121
122/// Determine if a package intersects with a Cpn.
123///
124/// # Safety
125/// The arguments should be non-null pointers.
126#[no_mangle]
127pub unsafe extern "C" fn pkgcraft_pkg_intersects_cpn(p: *mut Pkg, c: *mut Cpn) -> bool {
128    let pkg = try_ref_from_ptr!(p);
129    let cpn = try_ref_from_ptr!(c);
130    pkg.intersects(cpn)
131}
132
133/// Return the string for a package.
134///
135/// # Safety
136/// The argument must be a non-null Pkg pointer.
137#[no_mangle]
138pub unsafe extern "C" fn pkgcraft_pkg_str(p: *mut Pkg) -> *mut c_char {
139    let pkg = try_ref_from_ptr!(p);
140    try_ptr_from_str!(pkg.to_string())
141}
142
143/// Return the hash value for a package.
144///
145/// # Safety
146/// The argument must be a non-null Pkg pointer.
147#[no_mangle]
148pub unsafe extern "C" fn pkgcraft_pkg_hash(p: *mut Pkg) -> u64 {
149    let pkg = try_ref_from_ptr!(p);
150    hash(pkg)
151}
152
153/// Return the restriction for a package.
154///
155/// # Safety
156/// The argument must be a non-null Pkg pointer.
157#[no_mangle]
158pub unsafe extern "C" fn pkgcraft_pkg_restrict(p: *mut Pkg) -> *mut Restrict {
159    let pkg = try_ref_from_ptr!(p);
160    Box::into_raw(Box::new(pkg.into()))
161}
162
163/// Determine if a restriction matches a package.
164///
165/// # Safety
166/// The arguments must be valid Restrict and Pkg pointers.
167#[no_mangle]
168pub unsafe extern "C" fn pkgcraft_pkg_restrict_matches(p: *mut Pkg, r: *mut Restrict) -> bool {
169    let pkg = try_ref_from_ptr!(p);
170    let r = try_ref_from_ptr!(r);
171    r.matches(pkg)
172}
173
174/// Free an package.
175///
176/// # Safety
177/// The argument must be a non-null Pkg pointer or NULL.
178#[no_mangle]
179pub unsafe extern "C" fn pkgcraft_pkg_free(p: *mut Pkg) {
180    if !p.is_null() {
181        unsafe { drop(Box::from_raw(p)) };
182    }
183}