ek-ctp 0.9.5

CTP gateway for the enkeep ek ecosystem: MD/TD session drivers mapping CTP wire rows onto ek-data objects over the ek-event bus (pure-logic core; the CTP SDK ships inside this package and native bridging lands behind the optional `native` feature).
Documentation
//! native 层共用工具:跨 ABI 的 C 字符串搬运。
//!
//! 纪律:裸指针操作只允许出现在本模块与 [`super::md`]/[`super::td`] 的 `extern "C"`
//! 包装里,上层只见安全类型。
//!
//! 编码约定(D-NATIVE-ENC):Rust 侧一律用 **UTF-8** 传参,GBK↔UTF-8 的转换全部
//! 发生在 shim 内(`native/shim/ek_ctp_pod.cpp` 的 `ek_utf8_*`/`ek_gbk_*` 助手),
//! 因为 CTP 的 `char[]` 字段是本地码页(GBK)而 Rust 字符串是 UTF-8。

use std::ffi::{CStr, CString, c_char};

/// 把 shim 返回的 `const char*` 借成 `String`;空指针 → `None`。
///
/// # Safety
///
/// `p` 必须是空指针,或指向一个以 NUL 结尾、且在**下次对本句柄的调用前**始终有效的
/// C 字符串(shim 返回的静态/句柄期缓冲满足该条件)。
pub unsafe fn borrow_cstr(p: *const c_char) -> Option<String> {
    if p.is_null() {
        return None;
    }
    // SAFETY: 由本函数的 Safety 契约保证;空指针已在上面挡掉。
    Some(unsafe { CStr::from_ptr(p) }.to_string_lossy().into_owned())
}

/// 把 Rust 字符串转成 C 字符串(UTF-8 字节;GBK 转换在 shim 内做)。
///
/// 含内嵌 NUL 属调用方契约违背:直接 panic,**不静默截断**(静默截断会让下单参数
/// 变成另一个值,是不可审计的错)。
pub fn cstring(value: &str, what: &str) -> CString {
    CString::new(value)
        .unwrap_or_else(|_| panic!("ek-ctp native: {what} contains an interior NUL byte"))
}

/// shim 层最近一次失败的文本(无失败则为 `None`)。
///
/// MD/TD 共用同一份(它是 shim 级的静态缓冲,不是某个会话的属性)。
pub fn last_error() -> Option<String> {
    // SAFETY: shim 保证返回 NUL 结尾、且在下一次调用前有效的静态缓冲。
    let p = unsafe { ek_shim_last_error() };
    // SAFETY: 同上。
    unsafe { borrow_cstr(p) }
}

unsafe extern "C" {
    fn ek_shim_last_error() -> *const c_char;
}