Skip to main content

tipc_std/
ffi.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 KylinSoft Co., Ltd. <https://www.kylinos.cn/>
3// See LICENSES for license details.
4
5//! FFI types for tipc-std.
6
7pub use alloc_crate::ffi::CString;
8use alloc_crate::vec::Vec;
9
10use crate::alloc_crate;
11
12/// Error returned when creating a `CString` fails.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum TryNewError {
15    /// An interior nul byte was found at the given position.
16    NulError(usize, Vec<u8>),
17    /// Memory allocation failed.
18    AllocError,
19}
20
21/// A CString-like type that uses fallible allocation.
22pub struct FallibleCString(CString);
23
24impl FallibleCString {
25    /// Creates a new `FallibleCString` from a byte slice without nul check.
26    ///
27    /// # Safety
28    ///
29    /// The caller must ensure `v` contains no nul bytes and has a nul
30    /// terminator.
31    pub unsafe fn from_vec_unchecked(v: Vec<u8>) -> Result<Self, TryNewError> {
32        // SAFETY: caller guarantees no interior nul + nul terminated.
33        let cs = unsafe { CString::from_vec_unchecked(v) };
34        Ok(FallibleCString(cs))
35    }
36
37    /// Creates a new `FallibleCString` from a byte slice.
38    pub fn new(v: Vec<u8>) -> Result<Self, TryNewError> {
39        match CString::new(v) {
40            Ok(cs) => Ok(FallibleCString(cs)),
41            Err(e) => Err(TryNewError::NulError(e.nul_position(), e.into_vec())),
42        }
43    }
44}
45
46impl core::ops::Deref for FallibleCString {
47    type Target = CString;
48
49    fn deref(&self) -> &Self::Target {
50        &self.0
51    }
52}
53
54impl From<crate::alloc::AllocError> for TryNewError {
55    fn from(_err: crate::alloc::AllocError) -> Self {
56        TryNewError::AllocError
57    }
58}