Skip to content

Commit f7e3952

Browse files
committed
adds schedule test
1 parent 25c3438 commit f7e3952

File tree

5 files changed

+55
-10
lines changed

5 files changed

+55
-10
lines changed

rustler/src/schedule.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustler_sys::c_char;
33
use crate::codegen_runtime::{NifReturnable, NifReturned};
44
use crate::wrapper::ErlNifTaskFlags;
55
use crate::Env;
6+
use std::{ffi::CStr, marker::PhantomData};
67

78
pub enum SchedulerFlags {
89
Normal = ErlNifTaskFlags::ERL_NIF_NORMAL_JOB as isize,
@@ -42,12 +43,13 @@ pub fn consume_timeslice(env: Env, percent: i32) -> bool {
4243
/// ## Example:
4344
/// ```rust,ignore
4445
/// #[nif]
45-
/// fn factorial(input: u32, result: Option<u32>) -> Schedule<factorial, u32, u32> {
46+
/// fn factorial(input: u32, result: Option<u32>) -> Schedule<factorial, u32, u32, u32> {
4647
/// let result = result.unwrap_or(1);
4748
/// if input == 0 {
4849
/// Schedule::Result(result)
4950
/// } else {
50-
/// Schedule::Next2(factorial, input - 1, result * input)
51+
/// // alternatively `Schedule::Next2(std::marker::PhantomData, input - 1, result * input)`
52+
/// Schedule::next2(input - 1, result * input)
5153
/// }
5254
/// }
5355
/// ```
@@ -56,13 +58,34 @@ pub enum Schedule<N: crate::Nif, T, A = (), B = (), C = (), D = (), E = (), F =
5658
Result(T),
5759
/// Single- and multiple-argument variants that should reflect the scheduled
5860
/// NIF's function signature.
59-
Next(N, A),
60-
Next2(N, A, B),
61-
Next3(N, A, B, C),
62-
Next4(N, A, B, C, D),
63-
Next5(N, A, B, C, D, E),
64-
Next6(N, A, B, C, D, E, F),
65-
Next7(N, A, B, C, D, E, F, G),
61+
Next(PhantomData<N>, A),
62+
Next2(PhantomData<N>, A, B),
63+
Next3(PhantomData<N>, A, B, C),
64+
Next4(PhantomData<N>, A, B, C, D),
65+
Next5(PhantomData<N>, A, B, C, D, E),
66+
Next6(PhantomData<N>, A, B, C, D, E, F),
67+
Next7(PhantomData<N>, A, B, C, D, E, F, G),
68+
}
69+
70+
macro_rules! impl_func {
71+
($variant:ident $func_name:ident($($arg:ident : $ty:ty,)*)) => {
72+
/// Shorthand for creating a [`Schedule`] variant.
73+
///
74+
/// [`Schedule`]: crate::schedule::Schedule
75+
pub fn $func_name($($arg: $ty),*) -> Self {
76+
Self::$variant(PhantomData, $($arg),*)
77+
}
78+
};
79+
}
80+
81+
impl<N: crate::Nif, T, A, B, C, D, E, F, G> Schedule<N, T, A, B, C, D, E, F, G> {
82+
impl_func! { Next next(a: A,) }
83+
impl_func! { Next2 next2(a: A, b: B,) }
84+
impl_func! { Next3 next3(a: A, b: B, c: C,) }
85+
impl_func! { Next4 next4(a: A, b: B, c: C, d: D,) }
86+
impl_func! { Next5 next5(a: A, b: B, c: C, d: D, e: E,) }
87+
impl_func! { Next6 next6(a: A, b: B, c: C, d: D, e: E, f: F,) }
88+
impl_func! { Next7 next7(a: A, b: B, c: C, d: D, e: E, f: F, g: G,) }
6689
}
6790

6891
unsafe impl<N, T, A, B, C, D, E, F, G> NifReturnable for Schedule<N, T, A, B, C, D, E, F, G>
@@ -82,7 +105,7 @@ where
82105
macro_rules! branch {
83106
($($arg:tt),*) => (
84107
NifReturned::Reschedule {
85-
fun_name: std::ffi::CStr::from_ptr(N::NAME as *const c_char).into(),
108+
fun_name: CStr::from_ptr(N::NAME as *const c_char).into(),
86109
flags: SchedulerFlags::from(N::FLAGS as isize),
87110
fun: N::RAW_FUNC,
88111
args: vec![$($arg.encode(env).as_c_arg()),*],

rustler_tests/lib/rustler_test.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ defmodule RustlerTest do
7474

7575
def sum_range(_), do: err()
7676

77+
def scheduled_fac(_, _ \\ nil), do: err()
78+
7779
def bad_arg_error(), do: err()
7880
def atom_str_error(), do: err()
7981
def raise_atom_error(), do: err()

rustler_tests/native/rustler_test/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod test_nif_attrs;
1010
mod test_primitives;
1111
mod test_range;
1212
mod test_resource;
13+
mod test_schedule;
1314
mod test_term;
1415
mod test_thread;
1516

@@ -65,6 +66,7 @@ rustler::init!(
6566
test_codegen::tuplestruct_record_echo,
6667
test_dirty::dirty_cpu,
6768
test_dirty::dirty_io,
69+
test_schedule::scheduled_fac,
6870
test_range::sum_range,
6971
test_error::bad_arg_error,
7072
test_error::atom_str_error,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use rustler::schedule::Schedule;
2+
3+
#[rustler::nif]
4+
fn scheduled_fac(input: u32, result: Option<u32>) -> Schedule<scheduled_fac, u32, u32, u32> {
5+
let result = result.unwrap_or(1);
6+
if input == 0 {
7+
Schedule::Result(result)
8+
} else {
9+
Schedule::next2(input - 1, result * input)
10+
}
11+
}

rustler_tests/test/schedule_test.exs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defmodule RustlerTest.ScheduleTest do
2+
use ExUnit.Case, async: true
3+
4+
test "scheduled factorial" do
5+
assert 24 == RustlerTest.scheduled_fac(4)
6+
end
7+
end

0 commit comments

Comments
 (0)