Skip to content

Commit

Permalink
adds schedule test
Browse files Browse the repository at this point in the history
  • Loading branch information
sunny-g committed May 26, 2021
1 parent 25c3438 commit f7e3952
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 10 deletions.
43 changes: 33 additions & 10 deletions rustler/src/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use rustler_sys::c_char;
use crate::codegen_runtime::{NifReturnable, NifReturned};
use crate::wrapper::ErlNifTaskFlags;
use crate::Env;
use std::{ffi::CStr, marker::PhantomData};

pub enum SchedulerFlags {
Normal = ErlNifTaskFlags::ERL_NIF_NORMAL_JOB as isize,
Expand Down Expand Up @@ -42,12 +43,13 @@ pub fn consume_timeslice(env: Env, percent: i32) -> bool {
/// ## Example:
/// ```rust,ignore
/// #[nif]
/// fn factorial(input: u32, result: Option<u32>) -> Schedule<factorial, u32, u32> {
/// fn factorial(input: u32, result: Option<u32>) -> Schedule<factorial, u32, u32, u32> {
/// let result = result.unwrap_or(1);
/// if input == 0 {
/// Schedule::Result(result)
/// } else {
/// Schedule::Next2(factorial, input - 1, result * input)
/// // alternatively `Schedule::Next2(std::marker::PhantomData, input - 1, result * input)`
/// Schedule::next2(input - 1, result * input)
/// }
/// }
/// ```
Expand All @@ -56,13 +58,34 @@ pub enum Schedule<N: crate::Nif, T, A = (), B = (), C = (), D = (), E = (), F =
Result(T),
/// Single- and multiple-argument variants that should reflect the scheduled
/// NIF's function signature.
Next(N, A),
Next2(N, A, B),
Next3(N, A, B, C),
Next4(N, A, B, C, D),
Next5(N, A, B, C, D, E),
Next6(N, A, B, C, D, E, F),
Next7(N, A, B, C, D, E, F, G),
Next(PhantomData<N>, A),
Next2(PhantomData<N>, A, B),
Next3(PhantomData<N>, A, B, C),
Next4(PhantomData<N>, A, B, C, D),
Next5(PhantomData<N>, A, B, C, D, E),
Next6(PhantomData<N>, A, B, C, D, E, F),
Next7(PhantomData<N>, A, B, C, D, E, F, G),
}

macro_rules! impl_func {
($variant:ident $func_name:ident($($arg:ident : $ty:ty,)*)) => {
/// Shorthand for creating a [`Schedule`] variant.
///
/// [`Schedule`]: crate::schedule::Schedule
pub fn $func_name($($arg: $ty),*) -> Self {
Self::$variant(PhantomData, $($arg),*)
}
};
}

impl<N: crate::Nif, T, A, B, C, D, E, F, G> Schedule<N, T, A, B, C, D, E, F, G> {
impl_func! { Next next(a: A,) }
impl_func! { Next2 next2(a: A, b: B,) }
impl_func! { Next3 next3(a: A, b: B, c: C,) }
impl_func! { Next4 next4(a: A, b: B, c: C, d: D,) }
impl_func! { Next5 next5(a: A, b: B, c: C, d: D, e: E,) }
impl_func! { Next6 next6(a: A, b: B, c: C, d: D, e: E, f: F,) }
impl_func! { Next7 next7(a: A, b: B, c: C, d: D, e: E, f: F, g: G,) }
}

unsafe impl<N, T, A, B, C, D, E, F, G> NifReturnable for Schedule<N, T, A, B, C, D, E, F, G>
Expand All @@ -82,7 +105,7 @@ where
macro_rules! branch {
($($arg:tt),*) => (
NifReturned::Reschedule {
fun_name: std::ffi::CStr::from_ptr(N::NAME as *const c_char).into(),
fun_name: CStr::from_ptr(N::NAME as *const c_char).into(),
flags: SchedulerFlags::from(N::FLAGS as isize),
fun: N::RAW_FUNC,
args: vec![$($arg.encode(env).as_c_arg()),*],
Expand Down
2 changes: 2 additions & 0 deletions rustler_tests/lib/rustler_test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ defmodule RustlerTest do

def sum_range(_), do: err()

def scheduled_fac(_, _ \\ nil), do: err()

def bad_arg_error(), do: err()
def atom_str_error(), do: err()
def raise_atom_error(), do: err()
Expand Down
2 changes: 2 additions & 0 deletions rustler_tests/native/rustler_test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod test_nif_attrs;
mod test_primitives;
mod test_range;
mod test_resource;
mod test_schedule;
mod test_term;
mod test_thread;

Expand Down Expand Up @@ -65,6 +66,7 @@ rustler::init!(
test_codegen::tuplestruct_record_echo,
test_dirty::dirty_cpu,
test_dirty::dirty_io,
test_schedule::scheduled_fac,
test_range::sum_range,
test_error::bad_arg_error,
test_error::atom_str_error,
Expand Down
11 changes: 11 additions & 0 deletions rustler_tests/native/rustler_test/src/test_schedule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use rustler::schedule::Schedule;

#[rustler::nif]
fn scheduled_fac(input: u32, result: Option<u32>) -> Schedule<scheduled_fac, u32, u32, u32> {
let result = result.unwrap_or(1);
if input == 0 {
Schedule::Result(result)
} else {
Schedule::next2(input - 1, result * input)
}
}
7 changes: 7 additions & 0 deletions rustler_tests/test/schedule_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule RustlerTest.ScheduleTest do
use ExUnit.Case, async: true

test "scheduled factorial" do
assert 24 == RustlerTest.scheduled_fac(4)
end
end

0 comments on commit f7e3952

Please sign in to comment.