feat: update bmap-rs
This commit is contained in:
@@ -23,7 +23,7 @@ pub enum Error {
|
|||||||
BadCall,
|
BadCall,
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Marshaler(#[from] marshaler::Error),
|
Marshaler(#[from] marshaler::Error),
|
||||||
#[error("the length of given data iterator is too short when assigning struct array.")]
|
#[error("the length of given data iterator is too short when assigning data array.")]
|
||||||
OutOfLength,
|
OutOfLength,
|
||||||
#[error("bad cast to integral value")]
|
#[error("bad cast to integral value")]
|
||||||
BadIntCast(#[from] std::num::TryFromIntError),
|
BadIntCast(#[from] std::num::TryFromIntError),
|
||||||
@@ -42,7 +42,7 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||||||
///
|
///
|
||||||
/// Do **NOT** use this trait.
|
/// Do **NOT** use this trait.
|
||||||
/// It can not be hidden due to the limitation of Rust trait.
|
/// It can not be hidden due to the limitation of Rust trait.
|
||||||
pub trait AbstractPointer: Sized {
|
pub trait AbstractPointer {
|
||||||
/// Internal used function for fetching instance underlying pointer.
|
/// Internal used function for fetching instance underlying pointer.
|
||||||
///
|
///
|
||||||
/// Do **NOT** use this function.
|
/// Do **NOT** use this function.
|
||||||
@@ -74,7 +74,7 @@ trait BMFileObject: AbstractObject {}
|
|||||||
|
|
||||||
fn struct_assigner<O, T, I>(_: &O, ptr: *mut T, cnt: usize, it: &mut I) -> Result<()>
|
fn struct_assigner<O, T, I>(_: &O, ptr: *mut T, cnt: usize, it: &mut I) -> Result<()>
|
||||||
where
|
where
|
||||||
O: AbstractObject,
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
I: Iterator<Item = T>,
|
I: Iterator<Item = T>,
|
||||||
{
|
{
|
||||||
@@ -92,8 +92,8 @@ where
|
|||||||
|
|
||||||
pub struct StructIterator<'a, O, T>
|
pub struct StructIterator<'a, O, T>
|
||||||
where
|
where
|
||||||
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
O: AbstractObject,
|
|
||||||
{
|
{
|
||||||
ptr: *mut T,
|
ptr: *mut T,
|
||||||
cnt: usize,
|
cnt: usize,
|
||||||
@@ -103,8 +103,8 @@ where
|
|||||||
|
|
||||||
impl<'a, O, T> StructIterator<'a, O, T>
|
impl<'a, O, T> StructIterator<'a, O, T>
|
||||||
where
|
where
|
||||||
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
O: AbstractObject,
|
|
||||||
{
|
{
|
||||||
fn new(_: &'a O, ptr: *mut T, cnt: usize) -> Self {
|
fn new(_: &'a O, ptr: *mut T, cnt: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -118,8 +118,8 @@ where
|
|||||||
|
|
||||||
impl<'a, O, T> Iterator for StructIterator<'a, O, T>
|
impl<'a, O, T> Iterator for StructIterator<'a, O, T>
|
||||||
where
|
where
|
||||||
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
O: AbstractObject,
|
|
||||||
{
|
{
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
@@ -141,15 +141,15 @@ where
|
|||||||
|
|
||||||
impl<'a, O, T> FusedIterator for StructIterator<'a, O, T>
|
impl<'a, O, T> FusedIterator for StructIterator<'a, O, T>
|
||||||
where
|
where
|
||||||
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
O: AbstractObject,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, O, T> ExactSizeIterator for StructIterator<'a, O, T>
|
impl<'a, O, T> ExactSizeIterator for StructIterator<'a, O, T>
|
||||||
where
|
where
|
||||||
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
O: AbstractObject,
|
|
||||||
{
|
{
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
if self.i >= self.cnt {
|
if self.i >= self.cnt {
|
||||||
@@ -162,7 +162,7 @@ where
|
|||||||
|
|
||||||
fn struct_iterator<'a, O, T>(o: &'a O, ptr: *mut T, cnt: usize) -> Result<StructIterator<'a, O, T>>
|
fn struct_iterator<'a, O, T>(o: &'a O, ptr: *mut T, cnt: usize) -> Result<StructIterator<'a, O, T>>
|
||||||
where
|
where
|
||||||
O: AbstractObject,
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
{
|
{
|
||||||
Ok(StructIterator::new(o, ptr, cnt))
|
Ok(StructIterator::new(o, ptr, cnt))
|
||||||
@@ -258,27 +258,29 @@ impl BMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BMap {
|
impl BMap {
|
||||||
pub fn create_file_reader<'a, T>(
|
pub fn create_file_reader<'a, I, T>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
temp_folder: &str,
|
temp_folder: &str,
|
||||||
texture_folder: &str,
|
texture_folder: &str,
|
||||||
encodings: &[T],
|
encodings: I,
|
||||||
) -> Result<BMFileReader<'a>>
|
) -> Result<BMFileReader<'a>>
|
||||||
where
|
where
|
||||||
T: Into<Vec<u8>> + Copy,
|
I: Iterator<Item = T>,
|
||||||
|
T: Into<Vec<u8>>,
|
||||||
{
|
{
|
||||||
BMFileReader::new(self, file_name, temp_folder, texture_folder, encodings)
|
BMFileReader::new(self, file_name, temp_folder, texture_folder, encodings)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_file_writer<'a, T>(
|
pub fn create_file_writer<'a, I, T>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
temp_folder: &str,
|
temp_folder: &str,
|
||||||
texture_folder: &str,
|
texture_folder: &str,
|
||||||
encodings: &[T],
|
encodings: I,
|
||||||
) -> Result<BMFileWriter<'a>>
|
) -> Result<BMFileWriter<'a>>
|
||||||
where
|
where
|
||||||
T: Into<Vec<u8>> + Copy,
|
I: Iterator<Item = T>,
|
||||||
|
T: Into<Vec<u8>>,
|
||||||
{
|
{
|
||||||
BMFileWriter::new(self, temp_folder, texture_folder, encodings)
|
BMFileWriter::new(self, temp_folder, texture_folder, encodings)
|
||||||
}
|
}
|
||||||
@@ -330,15 +332,16 @@ pub struct BMFileReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BMFileReader<'a> {
|
impl<'a> BMFileReader<'a> {
|
||||||
fn new<T>(
|
fn new<I, T>(
|
||||||
_: &'a BMap,
|
_: &'a BMap,
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
temp_folder: &str,
|
temp_folder: &str,
|
||||||
texture_folder: &str,
|
texture_folder: &str,
|
||||||
encodings: &[T],
|
encodings: I,
|
||||||
) -> Result<Self>
|
) -> Result<Self>
|
||||||
where
|
where
|
||||||
T: Into<Vec<u8>> + Copy,
|
I: Iterator<Item = T>,
|
||||||
|
T: Into<Vec<u8>>,
|
||||||
{
|
{
|
||||||
let file_name = unsafe { marshaler::to_native_string(file_name)? };
|
let file_name = unsafe { marshaler::to_native_string(file_name)? };
|
||||||
let temp_folder = unsafe { marshaler::to_native_string(temp_folder)? };
|
let temp_folder = unsafe { marshaler::to_native_string(temp_folder)? };
|
||||||
@@ -401,9 +404,10 @@ pub struct BMFileWriter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BMFileWriter<'a> {
|
impl<'a> BMFileWriter<'a> {
|
||||||
fn new<T>(_: &'a BMap, temp_folder: &str, texture_folder: &str, encodings: &[T]) -> Result<Self>
|
fn new<I, T>(_: &'a BMap, temp_folder: &str, texture_folder: &str, encodings: I) -> Result<Self>
|
||||||
where
|
where
|
||||||
T: Into<Vec<u8>> + Copy,
|
I: Iterator<Item = T>,
|
||||||
|
T: Into<Vec<u8>>,
|
||||||
{
|
{
|
||||||
let temp_folder = unsafe { marshaler::to_native_string(temp_folder)? };
|
let temp_folder = unsafe { marshaler::to_native_string(temp_folder)? };
|
||||||
let texture_folder = unsafe { marshaler::to_native_string(texture_folder)? };
|
let texture_folder = unsafe { marshaler::to_native_string(texture_folder)? };
|
||||||
@@ -471,12 +475,12 @@ impl<'a> BMFileRW for BMFileWriter<'a> {}
|
|||||||
|
|
||||||
// region: Utility Functions
|
// region: Utility Functions
|
||||||
|
|
||||||
fn get_copyable_value<O, T>(
|
type FnCopyableValueGetter<T> = unsafe extern "C" fn(PBMVOID, CKID, param_out!(T)) -> BMBOOL;
|
||||||
o: &O,
|
type FnCopyableValueSetter<T> = unsafe extern "C" fn(PBMVOID, CKID, param_in!(T)) -> BMBOOL;
|
||||||
f: unsafe extern "C" fn(PBMVOID, CKID, param_out!(T)) -> BMBOOL,
|
|
||||||
) -> Result<T>
|
fn get_copyable_value<O, T>(o: &O, f: FnCopyableValueGetter<T>) -> Result<T>
|
||||||
where
|
where
|
||||||
O: AbstractObject,
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
{
|
{
|
||||||
let mut data = MaybeUninit::<T>::uninit();
|
let mut data = MaybeUninit::<T>::uninit();
|
||||||
@@ -488,25 +492,25 @@ where
|
|||||||
Ok(unsafe { data.assume_init() })
|
Ok(unsafe { data.assume_init() })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_copyable_value<O, T>(
|
fn set_copyable_value<O, T>(o: &O, f: FnCopyableValueSetter<T>, data: T) -> Result<()>
|
||||||
o: &O,
|
|
||||||
f: unsafe extern "C" fn(PBMVOID, CKID, param_in!(T)) -> BMBOOL,
|
|
||||||
data: T,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
where
|
||||||
O: AbstractObject,
|
O: AbstractObject + ?Sized,
|
||||||
T: Sized + Copy,
|
T: Sized + Copy,
|
||||||
{
|
{
|
||||||
bmap_exec!(f(o.get_pointer(), o.get_ckid(), arg_in!(data)));
|
bmap_exec!(f(o.get_pointer(), o.get_ckid(), arg_in!(data)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_string_value<O>(
|
// YYC MARK:
|
||||||
o: &O,
|
// Due to the pointer to C-style stirng is also copyable,
|
||||||
f: unsafe extern "C" fn(PBMVOID, CKID, param_out!(CKSTRING)) -> BMBOOL,
|
// so we can reuse these code.
|
||||||
) -> Result<Option<String>>
|
|
||||||
|
type FnStringValueGetter = FnCopyableValueGetter<CKSTRING>;
|
||||||
|
type FnStringValueSetter = FnCopyableValueSetter<CKSTRING>;
|
||||||
|
|
||||||
|
fn get_string_value<O>(o: &O, f: FnStringValueGetter) -> Result<Option<String>>
|
||||||
where
|
where
|
||||||
O: AbstractObject,
|
O: AbstractObject + ?Sized,
|
||||||
{
|
{
|
||||||
// Get raw string pointer
|
// Get raw string pointer
|
||||||
let data: CKSTRING = get_copyable_value(o, f)?;
|
let data: CKSTRING = get_copyable_value(o, f)?;
|
||||||
@@ -518,15 +522,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_string_value<O>(
|
fn set_string_value<O>(o: &O, f: FnStringValueSetter, s: Option<&str>) -> Result<()>
|
||||||
o: &O,
|
|
||||||
f: unsafe extern "C" fn(PBMVOID, CKID, param_in!(CKSTRING)) -> BMBOOL,
|
|
||||||
s: Option<&str>,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
where
|
||||||
O: AbstractObject,
|
O: AbstractObject + ?Sized,
|
||||||
{
|
{
|
||||||
// Buold raw string pointer.
|
// Build raw string pointer.
|
||||||
let native = match s {
|
let native = match s {
|
||||||
Some(s) => Some(unsafe { marshaler::to_native_string(s)? }),
|
Some(s) => Some(unsafe { marshaler::to_native_string(s)? }),
|
||||||
None => None,
|
None => None,
|
||||||
@@ -558,7 +558,7 @@ pub trait BMTexture: BMObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// YYC MARK:
|
// YYC MARK:
|
||||||
// Although load_image and save_image is not a "value setter",
|
// Although "load_image" and "save_image" is not a "value setter",
|
||||||
// but they have same function signature so we can reuse those code.
|
// but they have same function signature so we can reuse those code.
|
||||||
fn load_image(&mut self, filepath: &str) -> Result<()> {
|
fn load_image(&mut self, filepath: &str) -> Result<()> {
|
||||||
set_string_value(self, bmap::BMTexture_LoadImage, Some(filepath))
|
set_string_value(self, bmap::BMTexture_LoadImage, Some(filepath))
|
||||||
@@ -614,12 +614,24 @@ pub trait BMMaterial: BMObject {
|
|||||||
set_copyable_value(self, bmap::BMMaterial_SetSpecularPower, power)
|
set_copyable_value(self, bmap::BMMaterial_SetSpecularPower, power)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn get_texture(&self) -> Result<Option<Box<dyn BMTexture>>> {
|
// YYC MARK:
|
||||||
// todo!();
|
// We use "value getter" to get CKID first then convert it to our instance.
|
||||||
// }
|
// Same pattern for using "value setter".
|
||||||
// fn set_texture(&mut self, texture: Option<&dyn BMTexture>) -> Result<()> {
|
fn get_texture(&self) -> Result<Option<Box<dyn BMTexture>>> {
|
||||||
// todo!();
|
let ckid: CKID = get_copyable_value(self, bmap::BMMaterial_GetTexture)?;
|
||||||
// }
|
Ok(if ckid == INVALID_CKID {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Box::new(BMTextureImpl::new(, self.get_pointer(), ckid)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn set_texture(&mut self, texture: Option<&dyn BMTexture>) -> Result<()> {
|
||||||
|
let ckid: CKID = match texture {
|
||||||
|
Some(texture) => unsafe { texture.get_ckid() },
|
||||||
|
None => INVALID_CKID,
|
||||||
|
};
|
||||||
|
set_copyable_value(self, bmap::BMMaterial_SetTexture, ckid)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_texture_border_color(&self) -> Result<bmap::VxColor> {
|
fn get_texture_border_color(&self) -> Result<bmap::VxColor> {
|
||||||
let intermediary = get_copyable_value(self, bmap::BMMaterial_GetTextureBorderColor)?;
|
let intermediary = get_copyable_value(self, bmap::BMMaterial_GetTextureBorderColor)?;
|
||||||
@@ -883,7 +895,7 @@ macro_rules! libobj_struct {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct $name<'a, RW>
|
struct $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
handle: PBMVOID,
|
handle: PBMVOID,
|
||||||
id: CKID,
|
id: CKID,
|
||||||
@@ -896,7 +908,7 @@ macro_rules! libobj_impl_new {
|
|||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
impl<'a, RW> $name<'a, RW>
|
impl<'a, RW> $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
fn new(_: &'a RW, handle: PBMVOID, id: CKID) -> Self {
|
fn new(_: &'a RW, handle: PBMVOID, id: CKID) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -913,18 +925,18 @@ macro_rules! libobj_impl_eq_ord_hash {
|
|||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
impl<'a, RW> PartialEq for $name<'a, RW>
|
impl<'a, RW> PartialEq for $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.handle == other.handle && self.id == other.id
|
self.handle == other.handle && self.id == other.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, RW> Eq for $name<'a, RW> where RW: BMFileRW {}
|
impl<'a, RW> Eq for $name<'a, RW> where RW: BMFileRW + ?Sized {}
|
||||||
|
|
||||||
impl<'a, RW> PartialOrd for $name<'a, RW>
|
impl<'a, RW> PartialOrd for $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
match self.handle.partial_cmp(&other.handle) {
|
match self.handle.partial_cmp(&other.handle) {
|
||||||
@@ -936,7 +948,7 @@ macro_rules! libobj_impl_eq_ord_hash {
|
|||||||
|
|
||||||
impl<'a, RW> Ord for $name<'a, RW>
|
impl<'a, RW> Ord for $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
match self.handle.cmp(&other.handle) {
|
match self.handle.cmp(&other.handle) {
|
||||||
@@ -948,7 +960,7 @@ macro_rules! libobj_impl_eq_ord_hash {
|
|||||||
|
|
||||||
impl<'a, RW> Hash for $name<'a, RW>
|
impl<'a, RW> Hash for $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
@@ -962,7 +974,7 @@ macro_rules! libobj_impl_abstract_object {
|
|||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
impl<'a, RW> AbstractPointer for $name<'a, RW>
|
impl<'a, RW> AbstractPointer for $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
unsafe fn get_pointer(&self) -> PBMVOID {
|
unsafe fn get_pointer(&self) -> PBMVOID {
|
||||||
self.handle
|
self.handle
|
||||||
@@ -971,7 +983,7 @@ macro_rules! libobj_impl_abstract_object {
|
|||||||
|
|
||||||
impl<'a, RW> AbstractObject for $name<'a, RW>
|
impl<'a, RW> AbstractObject for $name<'a, RW>
|
||||||
where
|
where
|
||||||
RW: BMFileRW,
|
RW: BMFileRW + ?Sized,
|
||||||
{
|
{
|
||||||
unsafe fn get_ckid(&self) -> CKID {
|
unsafe fn get_ckid(&self) -> CKID {
|
||||||
self.id
|
self.id
|
||||||
@@ -982,7 +994,7 @@ macro_rules! libobj_impl_abstract_object {
|
|||||||
|
|
||||||
macro_rules! libobj_impl_obj_trait {
|
macro_rules! libobj_impl_obj_trait {
|
||||||
($name:ident, $trait:ident) => {
|
($name:ident, $trait:ident) => {
|
||||||
impl<'a, RW> $trait for $name<'a, RW> where RW: BMFileRW {}
|
impl<'a, RW> $trait for $name<'a, RW> where RW: BMFileRW + ?Sized {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1095,6 +1107,8 @@ impl<'a> BMMeshTrans<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> BMMeshTrans<'a> {}
|
||||||
|
|
||||||
impl<'a> Drop for BMMeshTrans<'a> {
|
impl<'a> Drop for BMMeshTrans<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let _ = unsafe { bmap::BMMeshTrans_Delete(self.handle) };
|
let _ = unsafe { bmap::BMMeshTrans_Delete(self.handle) };
|
||||||
|
|||||||
@@ -67,9 +67,10 @@ pub unsafe fn from_native_string_array(ptr: PCKSTRING) -> Result<Vec<String>> {
|
|||||||
Ok(rv)
|
Ok(rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn to_native_string_array<T>(words: &[T]) -> Result<BMStringArray>
|
pub unsafe fn to_native_string_array<I, T>(words: I) -> Result<BMStringArray>
|
||||||
where
|
where
|
||||||
T: Into<Vec<u8>> + Copy,
|
I: Iterator<Item = T>,
|
||||||
|
T: Into<Vec<u8>>,
|
||||||
{
|
{
|
||||||
BMStringArray::new(words)
|
BMStringArray::new(words)
|
||||||
}
|
}
|
||||||
@@ -80,14 +81,14 @@ pub struct BMStringArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BMStringArray {
|
impl BMStringArray {
|
||||||
fn new<T>(words: &[T]) -> Result<Self>
|
fn new<I, T>(words: I) -> Result<Self>
|
||||||
where
|
where
|
||||||
T: Into<Vec<u8>> + Copy,
|
I: Iterator<Item = T>,
|
||||||
|
T: Into<Vec<u8>>,
|
||||||
{
|
{
|
||||||
// Build array items
|
// Build array items
|
||||||
let array_items = words
|
let array_items = words
|
||||||
.iter()
|
.map(|word| CString::new(word))
|
||||||
.map(|word| CString::new(*word))
|
|
||||||
.collect::<std::result::Result<Vec<CString>, std::ffi::NulError>>()?;
|
.collect::<std::result::Result<Vec<CString>, std::ffi::NulError>>()?;
|
||||||
// Build array body.
|
// Build array body.
|
||||||
// In theory, move operation will not affect data allocated on heap.
|
// In theory, move operation will not affect data allocated on heap.
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ use bmap_rs::bmap_wrapper as bmap;
|
|||||||
fn test_complete() {
|
fn test_complete() {
|
||||||
assert!(bmap::BMap::is_available());
|
assert!(bmap::BMap::is_available());
|
||||||
bmap::BMap::with_bmap(|b| {
|
bmap::BMap::with_bmap(|b| {
|
||||||
let r = b.create_file_reader("", "", "", &[""]);
|
let r = b.create_file_reader("", "", "", std::iter::once(""));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user