Skip to content

Commit

Permalink
Remove lifetimes
Browse files Browse the repository at this point in the history
  • Loading branch information
zshipko committed May 28, 2022
1 parent c23918a commit 769db58
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 183 deletions.
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Unreleased

- Removed `IntoValue` and added `ToValue`
- Removed `IntoValue` and added `ToValue` because it now accepts a reference to self
- `Custom` types now have to be wrapped in a `Pointer<T>`
- Added `ocaml::import!` macro for calling OCaml functions from Rust
- Added `ocaml::sig` proc-macro for generating `external` and type signatures
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Defining the `OCAML_VERSION` and `OCAML_WHERE_PATH` variables is useful for savi
### Features

- `derive`
* enabled by default, adds `#[ocaml::func]` and friends and `derive` implementations for `FromValue` and `IntoValue`
* enabled by default, adds `#[ocaml::func]` and friends and `derive` implementations for `FromValue` and `ToValue`
- `link`
* link the native OCaml runtime, this should only be used when no OCaml code will be linked statically
- `no-std`
Expand All @@ -75,8 +75,8 @@ Defining the `OCAML_VERSION` and `OCAML_WHERE_PATH` variables is useful for savi
### Examples

```rust
// Automatically derive `IntoValue` and `FromValue`
#[derive(ocaml::IntoValue, ocaml::FromValue)]
// Automatically derive `ToValue` and `FromValue`
#[derive(ocaml::ToValue, ocaml::FromValue)]
#[ocaml::sig("{name: string; i: int}")]
struct Example<'a> {
name: &'a str,
Expand Down Expand Up @@ -198,7 +198,7 @@ This chart contains the mapping between Rust and OCaml types used by `ocaml::fun
| `BTreeMap<A, B>` | `('a, 'b) list` |
| `LinkedList<A>` | `'a list` |

NOTE: Even though `&[Value]` is specifically marked as no copy, any type like `Option<Value>` would also qualify since the inner value is not converted to a Rust type. However, `Option<String>` will do full unmarshaling into Rust types. Another thing to note: `FromValue` for `str` and `&[u8]` is zero-copy, however `IntoValue` for `str` and `&[u8]` creates a new value - this is necessary to ensure the string is registered with the OCaml runtime.
NOTE: Even though `&[Value]` is specifically marked as no copy, any type like `Option<Value>` would also qualify since the inner value is not converted to a Rust type. However, `Option<String>` will do full unmarshaling into Rust types. Another thing to note: `FromValue` for `str` and `&[u8]` is zero-copy, however `ToValue` for `str` and `&[u8]` creates a new value - this is necessary to ensure the string is registered with the OCaml runtime.

If you're concerned with minimizing allocations/conversions you should use `Value` type directly.

Expand Down
8 changes: 5 additions & 3 deletions derive/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ pub fn intovalue_derive(mut s: synstructure::Structure) -> proc_macro::TokenStre
}
});

let g = &s.ast().generics;
s.gen_impl(quote! {
gen unsafe impl ocaml::ToValue for @Self {
gen unsafe impl #g ocaml::ToValue for @Self {
fn to_value(&self, gc: &ocaml::Runtime) -> ocaml::Value {
let mut value = ocaml::Value::unit();
match self {
Expand All @@ -131,6 +132,7 @@ pub fn fromvalue_derive(s: synstructure::Structure) -> proc_macro::TokenStream {
} else {
Attrs::default()
};
let g = &s.ast().generics;
let body = s.variants().iter().map(|variant| {
let arity = variant.bindings().len();
let tag_ref = if arity > 0 {
Expand Down Expand Up @@ -167,7 +169,7 @@ pub fn fromvalue_derive(s: synstructure::Structure) -> proc_macro::TokenStream {
});
if attrs.unboxed {
s.gen_impl(quote! {
gen unsafe impl<'from_value_lifetime> ocaml::FromValue<'from_value_lifetime> for @Self {
gen unsafe impl #g ocaml::FromValue for @Self {
fn from_value(value: ocaml::Value) -> Self {
#(#body),*
}
Expand All @@ -186,7 +188,7 @@ pub fn fromvalue_derive(s: synstructure::Structure) -> proc_macro::TokenStream {
})
};
s.gen_impl(quote! {
gen unsafe impl<'from_value_lifetime> ocaml::FromValue<'from_value_lifetime> for @Self {
gen unsafe impl #g ocaml::FromValue for @Self {
fn from_value(value: ocaml::Value) -> Self {
unsafe {
let is_block = value.is_block();
Expand Down
42 changes: 20 additions & 22 deletions src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ macro_rules! value_i {
}
}

unsafe impl<'a> FromValue<'a> for $t {
unsafe impl FromValue for $t {
fn from_value(v: $crate::Value) -> $t {
unsafe { v.int_val() as $t }
}
Expand All @@ -39,7 +39,7 @@ macro_rules! value_f {
}
}

unsafe impl<'a> FromValue<'a> for $t {
unsafe impl FromValue for $t {
fn from_value(v: $crate::Value) -> $t {
unsafe { v.f64_val () as $t }
}
Expand All @@ -59,7 +59,7 @@ unsafe impl ToValue for i64 {
}
}

unsafe impl<'a> FromValue<'a> for i64 {
unsafe impl FromValue for i64 {
fn from_value(v: Value) -> i64 {
unsafe { v.int64_val() }
}
Expand All @@ -71,7 +71,7 @@ unsafe impl ToValue for u64 {
}
}

unsafe impl<'a> FromValue<'a> for u64 {
unsafe impl FromValue for u64 {
fn from_value(v: Value) -> u64 {
unsafe { v.int64_val() as u64 }
}
Expand All @@ -83,7 +83,7 @@ unsafe impl ToValue for i32 {
}
}

unsafe impl<'a> FromValue<'a> for i32 {
unsafe impl FromValue for i32 {
fn from_value(v: Value) -> i32 {
unsafe { v.int32_val() }
}
Expand All @@ -101,7 +101,7 @@ impl Incr {

macro_rules! tuple_impl {
($($t:ident: $n:tt),*) => {
unsafe impl<'a, $($t: FromValue<'a>),*> FromValue<'a> for ($($t,)*) {
unsafe impl<$($t: FromValue),*> FromValue for ($($t,)*) {
fn from_value(v: Value) -> ($($t,)*) {
let mut i = Incr(0);
#[allow(unused)]
Expand Down Expand Up @@ -165,7 +165,7 @@ unsafe impl ToValue for bool {
}
}

unsafe impl<'a> FromValue<'a> for bool {
unsafe impl FromValue for bool {
fn from_value(v: Value) -> bool {
unsafe { v.int_val() != 0 }
}
Expand All @@ -179,7 +179,7 @@ unsafe impl ToValue for String {
}

#[cfg(not(feature = "no-std"))]
unsafe impl<'a> FromValue<'a> for String {
unsafe impl FromValue for String {
fn from_value(value: Value) -> String {
unsafe { value.string_val().into() }
}
Expand All @@ -191,11 +191,11 @@ unsafe impl ToValue for () {
}
}

unsafe impl<'a> FromValue<'a> for () {
unsafe impl FromValue for () {
fn from_value(_value: Value) {}
}

unsafe impl<'a, T: FromValue<'a>> FromValue<'a> for Option<T> {
unsafe impl<T: FromValue> FromValue for Option<T> {
fn from_value(value: Value) -> Option<T> {
if value.raw().0 == sys::NONE {
return None;
Expand All @@ -214,7 +214,7 @@ unsafe impl<T: ToValue> ToValue for Option<T> {
}
}

unsafe impl<'a> FromValue<'a> for &'a str {
unsafe impl<'a> FromValue for &'a str {
fn from_value(value: Value) -> &'a str {
unsafe {
let len = sys::caml_string_length(value.raw().0);
Expand All @@ -231,7 +231,7 @@ unsafe impl ToValue for &str {
}
}

unsafe impl<'a> FromValue<'a> for &'a mut str {
unsafe impl<'a> FromValue for &'a mut str {
fn from_value(value: Value) -> &'a mut str {
unsafe {
let len = sys::caml_string_length(value.raw().0);
Expand All @@ -248,7 +248,7 @@ unsafe impl ToValue for &mut str {
}
}

unsafe impl<'a> FromValue<'a> for &'a [u8] {
unsafe impl<'a> FromValue for &'a [u8] {
fn from_value(value: Value) -> &'a [u8] {
unsafe {
let len = sys::caml_string_length(value.raw().0);
Expand All @@ -264,7 +264,7 @@ unsafe impl ToValue for &[u8] {
}
}

unsafe impl<'a> FromValue<'a> for &'a mut [u8] {
unsafe impl<'a> FromValue for &'a mut [u8] {
fn from_value(value: Value) -> &'a mut [u8] {
unsafe {
let len = sys::caml_string_length(value.raw().0);
Expand All @@ -280,7 +280,7 @@ unsafe impl ToValue for &mut [u8] {
}
}

unsafe impl<const N: usize> FromValue<'static> for [u8; N] {
unsafe impl<const N: usize> FromValue for [u8; N] {
fn from_value(value: Value) -> Self {
unsafe {
let len = sys::caml_string_length(value.raw().0);
Expand Down Expand Up @@ -323,7 +323,7 @@ unsafe impl<V: 'static + ToValue> ToValue for Vec<V> {
}

#[cfg(not(feature = "no-std"))]
unsafe impl<'a, V: FromValue<'a>> FromValue<'a> for Vec<V> {
unsafe impl<V: FromValue> FromValue for Vec<V> {
fn from_value(v: Value) -> Vec<V> {
unsafe {
let len = crate::sys::caml_array_length(v.raw().0);
Expand All @@ -343,7 +343,7 @@ unsafe impl<'a, V: FromValue<'a>> FromValue<'a> for Vec<V> {
}
}

unsafe impl<'a> FromValue<'a> for &'a [Raw] {
unsafe impl<'a> FromValue for &'a [Raw] {
fn from_value(value: Value) -> &'a [Raw] {
unsafe {
::core::slice::from_raw_parts(
Expand All @@ -354,7 +354,7 @@ unsafe impl<'a> FromValue<'a> for &'a [Raw] {
}
}

unsafe impl<'a> FromValue<'a> for &'a mut [Raw] {
unsafe impl<'a> FromValue for &'a mut [Raw] {
fn from_value(value: Value) -> &'a mut [Raw] {
unsafe {
::core::slice::from_raw_parts_mut(
Expand All @@ -366,9 +366,7 @@ unsafe impl<'a> FromValue<'a> for &'a mut [Raw] {
}

#[cfg(not(feature = "no-std"))]
unsafe impl<'a, K: Ord + FromValue<'a>, V: FromValue<'a>> FromValue<'a>
for std::collections::BTreeMap<K, V>
{
unsafe impl<'a, K: Ord + FromValue, V: FromValue> FromValue for std::collections::BTreeMap<K, V> {
fn from_value(v: Value) -> std::collections::BTreeMap<K, V> {
let mut dest = std::collections::BTreeMap::new();
unsafe {
Expand Down Expand Up @@ -400,7 +398,7 @@ unsafe impl<K: ToValue, V: ToValue> ToValue for std::collections::BTreeMap<K, V>
}

#[cfg(not(feature = "no-std"))]
unsafe impl<'a, T: FromValue<'a>> FromValue<'a> for std::collections::LinkedList<T> {
unsafe impl<T: FromValue> FromValue for std::collections::LinkedList<T> {
fn from_value(v: Value) -> std::collections::LinkedList<T> {
let mut dest: std::collections::LinkedList<T> = std::collections::LinkedList::new();

Expand Down
2 changes: 1 addition & 1 deletion src/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Default for CustomOps {
/// #[cfg(feature = "derive")]
/// #[ocaml::func]
/// pub unsafe fn example() -> ocaml::Pointer<Example> {
/// ocaml::Pointer::alloc_custom(Example(123))
/// Example(123).into()
/// }
///
/// #[cfg(feature = "derive")]
Expand Down
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ unsafe impl<T: ToValue> ToValue for Result<T, Error> {
}
}

unsafe impl<'a, T: FromValue<'a>> FromValue<'a> for Result<T, crate::Error> {
unsafe impl<T: FromValue> FromValue for Result<T, crate::Error> {
fn from_value(value: Value) -> Result<T, crate::Error> {
unsafe {
if value.is_exception_result() {
Expand All @@ -252,7 +252,7 @@ unsafe impl<'a, T: FromValue<'a>> FromValue<'a> for Result<T, crate::Error> {
}
}

unsafe impl<'a, A: FromValue<'a>, B: FromValue<'a>> FromValue<'a> for Result<A, B> {
unsafe impl<A: FromValue, B: FromValue> FromValue for Result<A, B> {
fn from_value(value: Value) -> Result<A, B> {
unsafe { value.result() }
}
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ mod macros;

mod conv;
mod error;
mod pointer;
mod tag;
mod types;
mod util;
Expand All @@ -152,9 +153,10 @@ pub mod custom;

pub use crate::custom::Custom;
pub use crate::error::{CamlError, Error};
pub use crate::pointer::Pointer;
pub use crate::runtime::*;
pub use crate::tag::Tag;
pub use crate::types::{bigarray, Array, List, Pointer};
pub use crate::types::{bigarray, Array, List};
pub use crate::value::{FromValue, Raw, ToValue, Value};

#[cfg(not(feature = "no-std"))]
Expand Down
Loading

0 comments on commit 769db58

Please sign in to comment.