Skip to content

Commit

Permalink
Merge pull request #45 from lumen/tuple_size_1
Browse files Browse the repository at this point in the history
tuple_size/1
  • Loading branch information
bitwalker committed May 21, 2019
2 parents 1956b2d + eeed76a commit 5dd07cb
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
18 changes: 18 additions & 0 deletions lumen_runtime/src/otp/erlang.rs
Expand Up @@ -683,6 +683,24 @@ pub fn tl_1(list: Term, process: &mut Process) -> Result {
Ok(cons.tail())
}

pub fn tuple_size_1(tuple: Term, mut process: &mut Process) -> Result {
match tuple.tag() {
Tag::Boxed => {
let unboxed: &Term = tuple.unbox_reference();

match unboxed.tag() {
Tag::Arity => {
let tuple: &Tuple = tuple.unbox_reference();

Ok(tuple.size().into_process(&mut process))
}
_ => Err(bad_argument!(&mut process)),
}
}
_ => Err(bad_argument!(&mut process)),
}
}

// Private Functions

fn binary_existence_to_atom(
Expand Down
1 change: 1 addition & 0 deletions lumen_runtime/src/otp/erlang/tests.rs
Expand Up @@ -47,6 +47,7 @@ mod make_ref_0;
mod self_0;
mod size_1;
mod tl_1;
mod tuple_size_1;

fn list_term(mut process: &mut Process) -> Term {
let head_term = Term::str_to_atom("head", Existence::DoNotCare, &mut process).unwrap();
Expand Down
167 changes: 167 additions & 0 deletions lumen_runtime/src/otp/erlang/tests/tuple_size_1.rs
@@ -0,0 +1,167 @@
use super::*;

use std::sync::{Arc, RwLock};

use num_traits::Num;

use crate::environment::{self, Environment};
use crate::process::IntoProcess;

#[test]
fn with_atom_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::str_to_atom("atom", Existence::DoNotCare, &mut process).unwrap();

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_local_reference_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::local_reference(&mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_empty_list_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::EMPTY_LIST;

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_list_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = list_term(&mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_small_integer_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = 0usize.into_process(&mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_big_integer_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let big_integer_term = <BigInt as Num>::from_str_radix("576460752303423489", 10)
.unwrap()
.into_process(&mut process);

assert_bad_argument!(erlang::tuple_size_1(big_integer_term, &mut process), &mut process);
}

#[test]
fn with_float_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = 1.0.into_process(&mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_local_pid_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::local_pid(0, 0, &mut process).unwrap();

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_external_pid_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::external_pid(1, 0, 0, &mut process).unwrap();

assert_bad_argument!(
erlang::tuple_size_1(tuple, &mut process),
&mut process
);
}

#[test]
fn with_tuple_without_elements_is_zero() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let empty_tuple = Term::slice_to_tuple(&[], &mut process);
let zero_term = 0usize.into_process(&mut process);

assert_eq_in_process!(
erlang::tuple_size_1(empty_tuple, &mut process),
Ok(zero_term),
process
);
}

#[test]
fn with_tuple_with_elements_is_element_count() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let element_vec: Vec<Term> = (0..=2usize).map(|i| i.into_process(&mut process)).collect();
let element_slice: &[Term] = element_vec.as_slice();
let tuple = Term::slice_to_tuple(element_slice, &mut process);
let arity_term = 3usize.into_process(&mut process);

assert_eq_in_process!(
erlang::tuple_size_1(tuple, &mut process),
Ok(arity_term),
process
);
}

#[test]
fn with_map_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::slice_to_map(&[], &mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_heap_binary_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let tuple = Term::slice_to_binary(&[0, 1, 2], &mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

#[test]
fn with_subbinary_errors_badarg() {
let environment_rw_lock: Arc<RwLock<Environment>> = Default::default();
let process_rw_lock = environment::process(Arc::clone(&environment_rw_lock));
let mut process = process_rw_lock.write().unwrap();
let binary_term =
Term::slice_to_binary(&[0b0000_00001, 0b1111_1110, 0b1010_1011], &mut process);
let tuple = Term::subbinary(binary_term, 0, 7, 2, 1, &mut process);

assert_bad_argument!(erlang::tuple_size_1(tuple, &mut process), &mut process);
}

0 comments on commit 5dd07cb

Please sign in to comment.