atc_router/ffi/
mod.rs

1pub mod context;
2pub mod expression;
3pub mod router;
4pub mod schema;
5
6use crate::ast::Value;
7use cidr::IpCidr;
8use std::convert::TryFrom;
9use std::ffi;
10use std::net::IpAddr;
11use std::os::raw::c_char;
12use std::slice::from_raw_parts;
13
14pub const ERR_BUF_MAX_LEN: usize = 4096;
15
16#[derive(Debug)]
17#[repr(C)]
18pub enum CValue {
19    Str(*const u8, usize),
20    IpCidr(*const u8),
21    IpAddr(*const u8),
22    Int(i64),
23}
24
25impl TryFrom<&CValue> for Value {
26    type Error = String;
27
28    fn try_from(v: &CValue) -> Result<Self, Self::Error> {
29        Ok(match v {
30            CValue::Str(s, len) => Self::String(unsafe {
31                std::str::from_utf8(from_raw_parts(*s, *len))
32                    .map_err(|e| e.to_string())?
33                    .to_string()
34            }),
35            CValue::IpCidr(s) => Self::IpCidr(
36                unsafe {
37                    ffi::CStr::from_ptr(*s as *const c_char)
38                        .to_str()
39                        .map_err(|e| e.to_string())?
40                        .to_string()
41                }
42                .parse::<IpCidr>()
43                .map_err(|e| e.to_string())?,
44            ),
45            CValue::IpAddr(s) => Self::IpAddr(
46                unsafe {
47                    ffi::CStr::from_ptr(*s as *const c_char)
48                        .to_str()
49                        .map_err(|e| e.to_string())?
50                        .to_string()
51                }
52                .parse::<IpAddr>()
53                .map_err(|e| e.to_string())?,
54            ),
55            CValue::Int(i) => Self::Int(*i),
56        })
57    }
58}