ctp_rust/
api.rs

1//! 高级API模块
2//!
3//! 提供安全、易用的Rust API接口
4
5pub mod async_md_api;
6pub mod async_trader_api;
7pub mod md_api;
8pub mod trader_api;
9
10pub use async_md_api::AsyncMdApi;
11pub use async_trader_api::AsyncTraderApi;
12pub use md_api::{MdApi, MdSpiHandler};
13pub use trader_api::{TraderApi, TraderSpiHandler};
14
15use crate::error::{CtpError, CtpResult};
16use std::ffi::CString;
17
18// CTP API基础功能特质
19pub trait CtpApi {
20    // 获取API版本
21    fn get_version() -> CtpResult<String>;
22
23    // 初始化API
24    fn init(&mut self) -> CtpResult<()>;
25
26    // 释放API资源
27    fn release(&mut self);
28
29    // 获取当前交易日
30    fn get_trading_day(&self) -> CtpResult<String>;
31
32    // 注册前置机地址
33    fn register_front(&mut self, front_address: &str) -> CtpResult<()>;
34
35    // 等待API线程结束
36    fn join(&self) -> CtpResult<i32>;
37}
38
39// 将Rust字符串转换为C字符串
40pub(crate) fn to_cstring(s: &str) -> CtpResult<CString> {
41    CString::new(s).map_err(|e| CtpError::InvalidParameterError(format!("字符串转换失败: {}", e)))
42}
43
44// 检查指针是否为空
45#[allow(dead_code)]
46pub(crate) fn check_null_ptr<T>(ptr: *const T, name: &str) -> CtpResult<()> {
47    if ptr.is_null() {
48        return Err(CtpError::FfiError(format!("{} 指针为空", name)));
49    }
50    Ok(())
51}
52
53// 安全地从C字符串获取UTF-8字符串
54pub(crate) fn safe_cstr_to_string(ptr: *const i8) -> CtpResult<String> {
55    if ptr.is_null() {
56        return Ok(String::new());
57    }
58
59    unsafe { crate::encoding::GbkConverter::cstring_to_utf8(ptr) }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_to_cstring() {
68        let result = to_cstring("test");
69        assert!(result.is_ok());
70
71        let result = to_cstring("测试");
72        assert!(result.is_ok());
73    }
74
75    #[test]
76    fn test_check_null_ptr() {
77        let ptr: *const i32 = std::ptr::null();
78        assert!(check_null_ptr(ptr, "test").is_err());
79
80        let value = 42i32;
81        let ptr = &value as *const i32;
82        assert!(check_null_ptr(ptr, "test").is_ok());
83    }
84}