use rand::{random, thread_rng, Rng};
use crate::{BuiltInFunction, Error, Map, Result, Type, Value};
pub struct Random;
impl BuiltInFunction for Random {
fn name(&self) -> &'static str {
"random"
}
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
Error::expect_argument_amount(self, 1, arguments.len())?;
let list = arguments.first().unwrap().as_list()?;
let items = list.items();
let random_index = thread_rng().gen_range(0..items.len());
let random_argument = items.get(random_index).unwrap();
Ok(random_argument.clone())
}
fn r#type(&self) -> Type {
Type::Function {
parameter_types: vec![Type::List(Box::new(Type::Any))],
return_type: Box::new(Type::Any),
}
}
}
pub struct RandomInteger;
impl BuiltInFunction for RandomInteger {
fn name(&self) -> &'static str {
"random_integer"
}
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
Error::expect_argument_amount(self, 0, arguments.len())?;
Ok(Value::Integer(random()))
}
fn r#type(&self) -> Type {
Type::Function {
parameter_types: Vec::with_capacity(0),
return_type: Box::new(Type::Integer),
}
}
}
pub struct RandomFloat;
impl BuiltInFunction for RandomFloat {
fn name(&self) -> &'static str {
"random_float"
}
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
Error::expect_argument_amount(self, 0, arguments.len())?;
Ok(Value::Float(random()))
}
fn r#type(&self) -> Type {
Type::Function {
parameter_types: Vec::with_capacity(0),
return_type: Box::new(Type::Float),
}
}
}
pub struct RandomBoolean;
impl BuiltInFunction for RandomBoolean {
fn name(&self) -> &'static str {
"random_boolean"
}
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
Error::expect_argument_amount(self, 0, arguments.len())?;
Ok(Value::Boolean(random()))
}
fn r#type(&self) -> Type {
Type::Function {
parameter_types: Vec::with_capacity(0),
return_type: Box::new(Type::Boolean),
}
}
}