use crate::builtin_function::utils::{param_to_datatype, returns};
use crate::common::data_type::DataType;
use crate::common::errors::{ChapError, Result};
use crate::{common::executable::ExecutableLine, runtime::Runtime};
pub fn get(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> {
let p1 = param_to_datatype(runtime, executable.params.first(), executable.line_number)?;
let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?;
match (p1, p2) {
(DataType::List(list), DataType::Int(index)) => {
if let Ok(x) = usize::try_from(*index) {
if x == 0 {
return Err(ChapError::runtime_with_msg(
executable.line_number,
"list index starts from 1".to_string(),
));
}
let x = x - 1;
let value = list.get(x);
if let Some(value) = value {
returns(runtime, executable, value.clone())
} else {
Err(ChapError::runtime_with_msg(
executable.line_number,
"index out of bound".to_string(),
))
}
} else {
Err(ChapError::runtime_with_msg(
executable.line_number,
"negative index".to_string(),
))
}
}
(DataType::Map(map), DataType::String(key)) => {
let value = map.get(key);
if let Some(value) = value {
returns(runtime, executable, value.clone())
} else {
Err(ChapError::runtime_with_msg(
executable.line_number,
"key not found".to_string(),
))
}
}
_ => Err(ChapError::runtime_with_msg(
executable.line_number,
"correct form of 'get' function: <list | map>, <index | key> -> get -> $item"
.to_string(),
)),
}
}