Skip to content

Commit

Permalink
Merge pull request #19 from snipsco/add_conversion_for_Range
Browse files Browse the repository at this point in the history
Add conversion between <std::ops::Range> and <CRange>
  • Loading branch information
anthonyray authored Mar 23, 2020
2 parents bb15c70 + d6524f8 commit 5766e28
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 7 deletions.
2 changes: 1 addition & 1 deletion ffi-convert-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ffi-convert-derive"
version = "0.1.2"
version = "0.2.0"
authors = ["Sonos"]
edition = "2018"
license = "MIT OR Apache-2.0"
Expand Down
4 changes: 2 additions & 2 deletions ffi-convert-tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[package]
name = "ffi-convert-tests"
version = "0.1.1"
version = "0.2.0"
authors = ["Sonos"]
edition = "2018"

[dependencies]
failure = "0.1"
ffi-convert = "0.1.2"
ffi-convert = "0.2.0"
libc = "0.2.66"
11 changes: 11 additions & 0 deletions ffi-convert-tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::ops::Range;
use failure::{bail, Fallible};
use ffi_convert::*;

Expand Down Expand Up @@ -41,6 +42,7 @@ pub struct Pancake {
pub toppings: Vec<Topping>,
pub layers: Option<Vec<Layer>>,
pub is_delicious: bool,
pub range: Range<usize>,
}

#[repr(C)]
Expand All @@ -60,6 +62,7 @@ pub struct CPancake {
#[nullable]
layers: *const CArray<CLayer>,
is_delicious: u8,
pub range: CRange<i32>,
}

#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -156,6 +159,10 @@ mod tests {
subtitle: Some(String::from("first layer")),
}]),
is_delicious: true,
range: Range {
start: 20,
end: 30,
}
}
});

Expand All @@ -173,6 +180,10 @@ mod tests {
toppings: vec![],
layers: Some(vec![]),
is_delicious: true,
range: Range {
start: 50,
end: 100,
}
}
});
}
4 changes: 2 additions & 2 deletions ffi-convert/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ffi-convert"
version = "0.1.2"
version = "0.2.0"
authors = ["Sonos"]
edition = "2018"
license = "MIT OR Apache-2.0"
Expand All @@ -10,6 +10,6 @@ readme = "../README.md"
keywords = ["ffi"]

[dependencies]
ffi-convert-derive = "0.1.2"
ffi-convert-derive = "0.2.0"
failure = "0.1"
libc = "0.2"
80 changes: 78 additions & 2 deletions ffi-convert/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::ffi::CString;
use std::ptr::null;
use std::ops::Range;

use failure::{Error, ResultExt};

Expand Down Expand Up @@ -104,8 +105,6 @@ impl CDrop for CStringArray {
/// let ctoppings = CArray::<CPizzaTopping>::c_repr_of(toppings);
///
/// ```
///
///
#[repr(C)]
pub struct CArray<T> {
data_ptr: *const T,
Expand Down Expand Up @@ -164,3 +163,80 @@ impl<T> Drop for CArray<T> {
let _ = self.do_drop();
}
}

/// A utility type to represent range.
/// Note that the parametrized type T should have have `CReprOf` and `AsRust` trait implementated.
///
/// # Example
///
/// ```
/// use ffi_convert::{CReprOf, AsRust, CDrop, CRange};
/// use std::ops::Range;
///
/// #[derive(Clone, Debug, PartialEq)]
/// pub struct Foo {
/// pub range: Range<i32>
/// }
///
/// #[derive(AsRust, CDrop, CReprOf, Debug, PartialEq)]
/// #[target_type(Foo)]
/// pub struct CFoo {
/// pub range: CRange<i32>
/// }
///
/// let foo = Foo {
/// range: Range {
/// start: 20,
/// end: 30,
/// }
/// };
///
/// let c_foo = CFoo {
/// range: CRange {
/// start: 20,
/// end: 30,
/// }
/// };
///
/// let c_foo_converted = CFoo::c_repr_of(foo.clone()).unwrap();
/// assert_eq!(c_foo, c_foo_converted);
///
/// let foo_converted = c_foo.as_rust().unwrap();
/// assert_eq!(foo_converted, foo);
/// ```
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
pub struct CRange<T> {
pub start: T,
pub end: T,
}

impl<U: AsRust<V>, V: PartialOrd + PartialEq> AsRust<Range<V>> for CRange<U> {
fn as_rust(&self) -> Result<Range<V>, Error> {
Ok(Range {
start: self.start.as_rust()?,
end: self.end.as_rust()?,
})
}
}

impl<U: CReprOf<V> + CDrop, V: PartialOrd + PartialEq> CReprOf<Range<V>> for CRange<U> {
fn c_repr_of(input: Range<V>) -> Result<Self, Error> {
Ok(Self {
start: U::c_repr_of(input.start)?,
end: U::c_repr_of(input.end)?,
})
}
}

impl<T> CDrop for CRange<T> {
fn do_drop(&mut self) -> Result<(), Error> {
Ok(())
}
}

impl<T> Drop for CRange<T> {
fn drop(&mut self) {
let _ = self.do_drop();
}
}

0 comments on commit 5766e28

Please sign in to comment.