如何将数组转换为 snips-nlu-rs 白名单或黑名单?
How do I convert arrays to a snips-nlu-rs whitelist or blacklist?
我使用 snips 并构建了一个 C 库。我想使用 Rust 将库连接到我的 Node 环境。
JavaScript
var ffi = require('ffi');
const ArrayType = require('ref-array');
var nlu = require('./nlu');
const StringArray = ArrayType('string');
var nlulib = '../cargo/target/x86_64-apple-darwin/release/libp_public_transport_nlu.dylib'
var nlu = ffi.Library(nlulib, {
"load": ['pointer', ['string']],
"execute": ['string', ['pointer', 'string', StringArray]]
});
var ptrToEngine = nlu.load("../snips_public_transport_engine");
var responseNLU = nlu.execute(ptrToEngine, "myQuery", ['bestIntent'], ['worstIntent']);
生锈
#[no_mangle]
pub extern "C" fn execute(engine_pointer: *mut SnipsNluEngine, query: *const c_char, whitelist: &[u8], blacklist: &[u8]) -> CString {
let query_c_str = unsafe { CStr::from_ptr(query) };
let query_string = match query_c_str.to_str().map(|s| s.to_owned()){
Ok(string) => string,
Err(e) => e.to_string()
};
let engine = unsafe {
assert!(!engine_pointer.is_null());
&mut *engine_pointer
};
let result = engine.parse(query_string.trim(), None, None).unwrap();
let result_json = serde_json::to_string_pretty(&result).unwrap();
CString::new(result_json).unwrap()
}
engine.parse
函数expects Into<Option<Vec<&'a str>>>
as a parameter instead of None
,所以我需要将白名单和黑名单转换成这种格式
经过一番努力,我找到了解决办法。我知道,这不会是有史以来最好的,但它是一个解决方案:)
pub extern "C" fn execute(engine_pointer: *mut SnipsNluEngine, query: *const c_char, whitelist: *const *const c_char) -> CString {
let query_c_str = unsafe { CStr::from_ptr(query) };
let query_string = match query_c_str.to_str().map(|s| s.to_owned()){
Ok(string) => string,
Err(e) => e.to_string()
};
let engine = unsafe {
assert!(!engine_pointer.is_null());
&mut *engine_pointer
};
// count length of whitelist
let mut whitelist_count = 0;
let mut wc = whitelist;
unsafe {
while *wc != std::ptr::null() {
whitelist_count += 1;
wc = wc.offset(1);
}
}
// get single elements pointer from pointer
let sliced_whitelist = unsafe { slice::from_raw_parts(whitelist, whitelist_count) };
// get string for every pointer
let mut string_list_whitelist: Vec<String> = vec![];
for i in 0..whitelist_count {
let whitelist_element = sliced_whitelist[i];
let whitelist_value = unsafe { CStr::from_ptr(whitelist_element) };
let string_whitelist: String = match whitelist_value.to_str().map(|s| s.to_owned()){
Ok(string) => string,
Err(e) => e.to_string()
};
string_list_whitelist.insert(0, string_whitelist);
}
let mut snips_whitelist: Vec<&str> = vec![];
for i in 0..whitelist_count {
let whitelist_element_str: &str = &string_list_whitelist[i][..];
snips_whitelist.insert(0, whitelist_element_str);
}
// create an optional for the whitelist
let mut snips_whitelist_optional: Option<Vec<&str>> = None;
if whitelist_count != 0 {
snips_whitelist_optional = Some(snips_whitelist);
}
// parsing
let result = engine.parse(query_string.trim(), snips_whitelist_optional, snips_blacklist_optional).unwrap();
let result_json = serde_json::to_string_pretty(&result).unwrap();
CString::new(result_json).unwrap()
}
提示:必须在白名单字符串数组的末尾发送空指针(例如ref.NULL
)。或者,您可以将数组长度作为参数发送,而不是计算列表长度。
我使用 snips 并构建了一个 C 库。我想使用 Rust 将库连接到我的 Node 环境。
JavaScript
var ffi = require('ffi');
const ArrayType = require('ref-array');
var nlu = require('./nlu');
const StringArray = ArrayType('string');
var nlulib = '../cargo/target/x86_64-apple-darwin/release/libp_public_transport_nlu.dylib'
var nlu = ffi.Library(nlulib, {
"load": ['pointer', ['string']],
"execute": ['string', ['pointer', 'string', StringArray]]
});
var ptrToEngine = nlu.load("../snips_public_transport_engine");
var responseNLU = nlu.execute(ptrToEngine, "myQuery", ['bestIntent'], ['worstIntent']);
生锈
#[no_mangle]
pub extern "C" fn execute(engine_pointer: *mut SnipsNluEngine, query: *const c_char, whitelist: &[u8], blacklist: &[u8]) -> CString {
let query_c_str = unsafe { CStr::from_ptr(query) };
let query_string = match query_c_str.to_str().map(|s| s.to_owned()){
Ok(string) => string,
Err(e) => e.to_string()
};
let engine = unsafe {
assert!(!engine_pointer.is_null());
&mut *engine_pointer
};
let result = engine.parse(query_string.trim(), None, None).unwrap();
let result_json = serde_json::to_string_pretty(&result).unwrap();
CString::new(result_json).unwrap()
}
engine.parse
函数expects Into<Option<Vec<&'a str>>>
as a parameter instead of None
,所以我需要将白名单和黑名单转换成这种格式
经过一番努力,我找到了解决办法。我知道,这不会是有史以来最好的,但它是一个解决方案:)
pub extern "C" fn execute(engine_pointer: *mut SnipsNluEngine, query: *const c_char, whitelist: *const *const c_char) -> CString {
let query_c_str = unsafe { CStr::from_ptr(query) };
let query_string = match query_c_str.to_str().map(|s| s.to_owned()){
Ok(string) => string,
Err(e) => e.to_string()
};
let engine = unsafe {
assert!(!engine_pointer.is_null());
&mut *engine_pointer
};
// count length of whitelist
let mut whitelist_count = 0;
let mut wc = whitelist;
unsafe {
while *wc != std::ptr::null() {
whitelist_count += 1;
wc = wc.offset(1);
}
}
// get single elements pointer from pointer
let sliced_whitelist = unsafe { slice::from_raw_parts(whitelist, whitelist_count) };
// get string for every pointer
let mut string_list_whitelist: Vec<String> = vec![];
for i in 0..whitelist_count {
let whitelist_element = sliced_whitelist[i];
let whitelist_value = unsafe { CStr::from_ptr(whitelist_element) };
let string_whitelist: String = match whitelist_value.to_str().map(|s| s.to_owned()){
Ok(string) => string,
Err(e) => e.to_string()
};
string_list_whitelist.insert(0, string_whitelist);
}
let mut snips_whitelist: Vec<&str> = vec![];
for i in 0..whitelist_count {
let whitelist_element_str: &str = &string_list_whitelist[i][..];
snips_whitelist.insert(0, whitelist_element_str);
}
// create an optional for the whitelist
let mut snips_whitelist_optional: Option<Vec<&str>> = None;
if whitelist_count != 0 {
snips_whitelist_optional = Some(snips_whitelist);
}
// parsing
let result = engine.parse(query_string.trim(), snips_whitelist_optional, snips_blacklist_optional).unwrap();
let result_json = serde_json::to_string_pretty(&result).unwrap();
CString::new(result_json).unwrap()
}
提示:必须在白名单字符串数组的末尾发送空指针(例如ref.NULL
)。或者,您可以将数组长度作为参数发送,而不是计算列表长度。