1use std::cmp::Ordering;
2use std::ffi::{c_char, c_int};
3use std::ptr;
4
5use pkgcraft::dep::version::WithOp;
6use pkgcraft::dep::{Operator, Revision, Version};
7use pkgcraft::traits::Intersects;
8use pkgcraft::utils::hash;
9
10use crate::macros::*;
11use crate::panic::ffi_catch_panic;
12
13#[no_mangle]
20pub unsafe extern "C" fn pkgcraft_revision_new(s: *const c_char) -> *mut Revision {
21 ffi_catch_panic! {
22 let s = try_str_from_ptr!(s);
23 let rev = unwrap_or_panic!(Revision::try_new(s));
24 Box::into_raw(Box::new(rev))
25 }
26}
27
28#[no_mangle]
34pub unsafe extern "C" fn pkgcraft_revision_cmp(r1: *mut Revision, r2: *mut Revision) -> c_int {
35 let r1 = try_ref_from_ptr!(r1);
36 let r2 = try_ref_from_ptr!(r2);
37
38 match r1.cmp(r2) {
39 Ordering::Less => -1,
40 Ordering::Equal => 0,
41 Ordering::Greater => 1,
42 }
43}
44
45#[no_mangle]
50pub unsafe extern "C" fn pkgcraft_revision_hash(r: *mut Revision) -> u64 {
51 let rev = try_ref_from_ptr!(r);
52 hash(rev)
53}
54
55#[no_mangle]
60pub unsafe extern "C" fn pkgcraft_revision_str(r: *mut Revision) -> *mut c_char {
61 let rev = try_ref_from_ptr!(r);
62 try_ptr_from_str!(rev.as_str())
63}
64
65#[no_mangle]
70pub unsafe extern "C" fn pkgcraft_revision_free(r: *mut Revision) {
71 if !r.is_null() {
72 let _ = unsafe { Box::from_raw(r) };
73 }
74}
75
76#[no_mangle]
83pub unsafe extern "C" fn pkgcraft_version_new(s: *const c_char) -> *mut Version {
84 ffi_catch_panic! {
85 let s = try_str_from_ptr!(s);
86 let ver = unwrap_or_panic!(Version::try_new(s));
87 Box::into_raw(Box::new(ver))
88 }
89}
90
91#[no_mangle]
98pub unsafe extern "C" fn pkgcraft_version_parse(s: *const c_char) -> *const c_char {
99 ffi_catch_panic! {
100 let val = try_str_from_ptr!(s);
101 unwrap_or_panic!(Version::try_new(val));
102 s
103 }
104}
105
106#[no_mangle]
113pub unsafe extern "C" fn pkgcraft_version_op(v: *mut Version) -> u32 {
114 let ver = try_ref_from_ptr!(v);
115 ver.op().map(|x| x as u32).unwrap_or_default()
116}
117
118#[no_mangle]
125pub unsafe extern "C" fn pkgcraft_version_with_op(v: *mut Version, op: Operator) -> *mut Version {
126 ffi_catch_panic! {
127 let ver = try_ref_from_ptr!(v);
128 if ver.op() == Some(op) {
129 v
130 } else {
131 let ver = unwrap_or_panic!(ver.clone().with_op(op));
132 Box::into_raw(Box::new(ver))
133 }
134 }
135}
136
137#[no_mangle]
142pub unsafe extern "C" fn pkgcraft_version_base(v: *mut Version) -> *mut c_char {
143 let ver = try_ref_from_ptr!(v);
144 try_ptr_from_str!(ver.base())
145}
146
147#[no_mangle]
154pub unsafe extern "C" fn pkgcraft_version_op_from_str(s: *const c_char) -> u32 {
155 let s = try_str_from_ptr!(s);
156 s.parse::<Operator>().map(|x| x as u32).unwrap_or_default()
157}
158
159#[no_mangle]
161pub extern "C" fn pkgcraft_version_op_str(op: Operator) -> *mut c_char {
162 try_ptr_from_str!(op.as_ref())
163}
164
165#[no_mangle]
171pub unsafe extern "C" fn pkgcraft_version_cmp(v1: *mut Version, v2: *mut Version) -> c_int {
172 let v1 = try_ref_from_ptr!(v1);
173 let v2 = try_ref_from_ptr!(v2);
174
175 match v1.cmp(v2) {
176 Ordering::Less => -1,
177 Ordering::Equal => 0,
178 Ordering::Greater => 1,
179 }
180}
181
182#[no_mangle]
187pub unsafe extern "C" fn pkgcraft_version_intersects(v1: *mut Version, v2: *mut Version) -> bool {
188 let v1 = try_ref_from_ptr!(v1);
189 let v2 = try_ref_from_ptr!(v2);
190 v1.intersects(v2)
191}
192
193#[no_mangle]
200pub unsafe extern "C" fn pkgcraft_version_revision(v: *mut Version) -> *mut Revision {
201 let ver = try_ref_from_ptr!(v);
202 match ver.revision() {
203 Some(rev) => Box::into_raw(Box::new(rev.clone())),
204 None => ptr::null_mut(),
205 }
206}
207
208#[no_mangle]
213pub unsafe extern "C" fn pkgcraft_version_str(v: *mut Version) -> *mut c_char {
214 let ver = try_ref_from_ptr!(v);
215 try_ptr_from_str!(ver.to_string())
216}
217
218#[no_mangle]
223pub unsafe extern "C" fn pkgcraft_version_free(v: *mut Version) {
224 if !v.is_null() {
225 let _ = unsafe { Box::from_raw(v) };
226 }
227}
228
229#[no_mangle]
234pub unsafe extern "C" fn pkgcraft_version_hash(v: *mut Version) -> u64 {
235 let ver = try_ref_from_ptr!(v);
236 hash(ver)
237}