rice_ctypes/
lib.rs

1// Copyright (C) 2025 Matthew Waters <matthew@centricular.com>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9#![deny(missing_debug_implementations)]
10#![deny(missing_docs)]
11#![allow(clippy::missing_safety_doc)]
12
13//! # rice-ctypes
14//!
15//! Helper crate for providing C types for the rice API.
16
17use core::ffi::CStr;
18use core::ffi::{c_char, c_int};
19use core::net::SocketAddr;
20use core::str::FromStr;
21
22/// Errors when processing an operation.
23#[repr(i32)]
24#[derive(Debug, PartialEq, Eq, Copy, Clone)]
25pub enum RiceError {
26    /// Not an error. The operation was completed successfully.
27    Success = 0,
28    /// The operation failed for an unspecified reason.
29    Failed = -1,
30    /// A required resource was not found.
31    ResourceNotFound = -2,
32    /// The operation is already in progress.
33    AlreadyInProgress = -3,
34}
35
36/// A socket address.
37#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
38pub struct RiceAddress(SocketAddr);
39
40impl RiceAddress {
41    /// Create a new `RiceAddress`.
42    pub fn new(addr: SocketAddr) -> Self {
43        Self(addr)
44    }
45
46    /// Convert this `RiceAddress` into it's C API equivalent.
47    ///
48    /// The returned value should be converted back into the Rust equivalent using
49    /// `RiceAddress::into_rust_full()` in order to free the resource.
50    pub fn into_c_full(self) -> *const RiceAddress {
51        const_override(Box::into_raw(Box::new(self)))
52    }
53
54    /// Consume a C representation of a `RiceAddress` into the Rust equivalent.
55    pub unsafe fn into_rice_full(value: *const RiceAddress) -> Box<Self> {
56        Box::from_raw(mut_override(value))
57    }
58
59    /// Copy a C representation of a `RiceAddress` into the Rust equivalent.
60    pub unsafe fn into_rice_none(value: *const RiceAddress) -> Self {
61        let boxed = Box::from_raw(mut_override(value));
62        let ret = *boxed;
63        core::mem::forget(boxed);
64        ret
65    }
66
67    /// The inner representation of the [`RiceAddress`].
68    pub fn inner(self) -> SocketAddr {
69        self.0
70    }
71}
72
73impl core::ops::Deref for RiceAddress {
74    type Target = SocketAddr;
75    fn deref(&self) -> &Self::Target {
76        &self.0
77    }
78}
79
80/// Create a `RiceAddress` from a string representation of the socket address.
81pub unsafe fn rice_address_new_from_string(string: *const c_char) -> *mut RiceAddress {
82    let Ok(string) = CStr::from_ptr(string).to_str() else {
83        return core::ptr::null_mut();
84    };
85    let Ok(saddr) = SocketAddr::from_str(string) else {
86        return core::ptr::null_mut();
87    };
88
89    mut_override(RiceAddress::into_c_full(RiceAddress::new(saddr)))
90}
91
92/// Compare whether two `RiceAddress`es are equal.
93pub unsafe fn rice_address_cmp(addr: *const RiceAddress, other: *const RiceAddress) -> c_int {
94    match (addr.is_null(), other.is_null()) {
95        (true, true) => 0,
96        (true, false) => -1,
97        (false, true) => 1,
98        (false, false) => {
99            let addr = RiceAddress::into_rice_none(addr);
100            let other = RiceAddress::into_rice_none(other);
101            addr.cmp(&other) as c_int
102        }
103    }
104}
105
106/// Free a `RiceAddress`.
107pub unsafe fn rice_address_free(addr: *mut RiceAddress) {
108    if !addr.is_null() {
109        let _addr = Box::from_raw(addr);
110    }
111}
112
113/// The transport family
114#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115#[repr(u32)]
116pub enum RiceTransportType {
117    /// The UDP transport
118    Udp,
119    /// The TCP transport
120    Tcp,
121}
122
123fn mut_override<T>(val: *const T) -> *mut T {
124    val as *mut T
125}
126
127fn const_override<T>(val: *mut T) -> *const T {
128    val as *const T
129}