Add type checks
This commit is contained in:
parent
7c6a4e5ece
commit
fabcbdd216
@ -8,7 +8,7 @@ impl Tool for Transform {
|
|||||||
fn info(&self) -> ToolInfo<'static> {
|
fn info(&self) -> ToolInfo<'static> {
|
||||||
ToolInfo {
|
ToolInfo {
|
||||||
identifier: "transform",
|
identifier: "transform",
|
||||||
description: "Alter a collection by calling a function on each value.",
|
description: "Alter a list by calling a function on each value.",
|
||||||
group: "collections",
|
group: "collections",
|
||||||
inputs: vec![ValueType::ListExact(vec![
|
inputs: vec![ValueType::ListExact(vec![
|
||||||
ValueType::List,
|
ValueType::List,
|
||||||
@ -18,36 +18,27 @@ impl Tool for Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
fn run(&self, argument: &Value) -> Result<Value> {
|
||||||
let argument = argument.as_list()?;
|
let argument = self.check_type(argument)?;
|
||||||
let value = &argument[0];
|
|
||||||
let function = argument[1].as_function()?;
|
|
||||||
|
|
||||||
match value {
|
if let Value::List(list) = argument {
|
||||||
Value::String(_string) => todo!(),
|
let list = list[0].as_list()?;
|
||||||
Value::Float(_) => todo!(),
|
let function = list[1].as_function()?;
|
||||||
Value::Integer(_) => todo!(),
|
let mut mapped_list = Vec::with_capacity(list.len());
|
||||||
Value::Boolean(_) => todo!(),
|
|
||||||
Value::List(list) => {
|
|
||||||
let mut mapped_list = Vec::with_capacity(list.len());
|
|
||||||
|
|
||||||
for value in list {
|
for value in list {
|
||||||
let mut context = VariableMap::new();
|
let mut context = VariableMap::new();
|
||||||
|
|
||||||
context.set_value("input", value.clone())?;
|
context.set_value("input", value.clone())?;
|
||||||
|
|
||||||
let mapped_value = function.run_with_context(&mut context)?;
|
let mapped_value = function.run_with_context(&mut context)?;
|
||||||
|
|
||||||
mapped_list.push(mapped_value);
|
mapped_list.push(mapped_value);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Value::List(mapped_list))
|
|
||||||
}
|
}
|
||||||
Value::Empty => todo!(),
|
|
||||||
Value::Map(_map) => todo!(),
|
return Ok(Value::List(mapped_list));
|
||||||
Value::Table(_) => todo!(),
|
|
||||||
Value::Function(_) => todo!(),
|
|
||||||
Value::Time(_) => todo!(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.fail(argument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,22 +50,26 @@ impl Tool for String {
|
|||||||
identifier: "string",
|
identifier: "string",
|
||||||
description: "Stringify a value.",
|
description: "Stringify a value.",
|
||||||
group: "collections",
|
group: "collections",
|
||||||
inputs: vec![ValueType::Any],
|
inputs: vec![
|
||||||
|
ValueType::String,
|
||||||
|
ValueType::Function,
|
||||||
|
ValueType::Float,
|
||||||
|
ValueType::Integer,
|
||||||
|
ValueType::Boolean,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
fn run(&self, argument: &Value) -> Result<Value> {
|
||||||
let string = match argument.clone() {
|
let argument = self.check_type(argument)?;
|
||||||
Value::String(string) => string,
|
|
||||||
Value::List(_list) => todo!(),
|
let string = match argument {
|
||||||
Value::Map(_map) => todo!(),
|
Value::String(string) => string.clone(),
|
||||||
Value::Table(_table) => todo!(),
|
|
||||||
Value::Function(function) => function.to_string(),
|
Value::Function(function) => function.to_string(),
|
||||||
Value::Float(float) => float.to_string(),
|
Value::Float(float) => float.to_string(),
|
||||||
Value::Integer(integer) => integer.to_string(),
|
Value::Integer(integer) => integer.to_string(),
|
||||||
Value::Boolean(boolean) => boolean.to_string(),
|
Value::Boolean(boolean) => boolean.to_string(),
|
||||||
Value::Time(_) => todo!(),
|
_ => return self.fail(argument),
|
||||||
Value::Empty => todo!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Value::String(string))
|
Ok(Value::String(string))
|
||||||
@ -87,13 +82,15 @@ impl Tool for Count {
|
|||||||
fn info(&self) -> ToolInfo<'static> {
|
fn info(&self) -> ToolInfo<'static> {
|
||||||
ToolInfo {
|
ToolInfo {
|
||||||
identifier: "count",
|
identifier: "count",
|
||||||
description: "Return the number of items in a value.",
|
description: "Return the number of items in a collection.",
|
||||||
group: "collections",
|
group: "collections",
|
||||||
inputs: vec![ValueType::Any],
|
inputs: vec![ValueType::Any],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
fn run(&self, argument: &Value) -> Result<Value> {
|
||||||
|
let argument = self.check_type(argument)?;
|
||||||
|
|
||||||
let len = match argument {
|
let len = match argument {
|
||||||
Value::String(string) => string.chars().count(),
|
Value::String(string) => string.chars().count(),
|
||||||
Value::List(list) => list.len(),
|
Value::List(list) => list.len(),
|
||||||
@ -103,8 +100,8 @@ impl Tool for Count {
|
|||||||
| Value::Float(_)
|
| Value::Float(_)
|
||||||
| Value::Integer(_)
|
| Value::Integer(_)
|
||||||
| Value::Boolean(_)
|
| Value::Boolean(_)
|
||||||
| Value::Time(_) => 1,
|
| Value::Time(_)
|
||||||
Value::Empty => 0,
|
| Value::Empty => return self.fail(argument),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Value::Integer(len as i64))
|
Ok(Value::Integer(len as i64))
|
||||||
@ -119,12 +116,15 @@ impl Tool for CreateTable {
|
|||||||
identifier: "create_table",
|
identifier: "create_table",
|
||||||
description: "Define a new table with a list of column names and list of rows.",
|
description: "Define a new table with a list of column names and list of rows.",
|
||||||
group: "collections",
|
group: "collections",
|
||||||
inputs: vec![ValueType::ListExact(vec![ValueType::List, ValueType::List])],
|
inputs: vec![ValueType::ListExact(vec![
|
||||||
|
ValueType::ListOf(Box::new(ValueType::String)),
|
||||||
|
ValueType::ListOf(Box::new(ValueType::List)),
|
||||||
|
])],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
fn run(&self, argument: &Value) -> Result<Value> {
|
||||||
let argument = argument.as_list()?;
|
let argument = self.check_type(argument)?.as_list()?;
|
||||||
|
|
||||||
let column_name_inputs = argument[0].as_list()?;
|
let column_name_inputs = argument[0].as_list()?;
|
||||||
let mut column_names = Vec::with_capacity(column_name_inputs.len());
|
let mut column_names = Vec::with_capacity(column_name_inputs.len());
|
||||||
@ -160,49 +160,20 @@ impl Tool for Rows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
fn run(&self, argument: &Value) -> Result<Value> {
|
||||||
let table = argument.as_table()?;
|
let argument = self.check_type(argument)?;
|
||||||
|
|
||||||
let rows = table
|
if let Value::Table(table) = argument {
|
||||||
.rows()
|
let rows = table
|
||||||
.iter()
|
.rows()
|
||||||
.map(|row| Value::List(row.clone()))
|
.iter()
|
||||||
.collect();
|
.map(|row| Value::List(row.clone()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
Ok(Value::List(rows))
|
Ok(Value::List(rows))
|
||||||
}
|
} else {
|
||||||
}
|
self.fail(argument)
|
||||||
|
|
||||||
pub struct Get;
|
|
||||||
|
|
||||||
impl Tool for Get {
|
|
||||||
fn info(&self) -> ToolInfo<'static> {
|
|
||||||
ToolInfo {
|
|
||||||
identifier: "get",
|
|
||||||
description: "Retrieve a value from a collection.",
|
|
||||||
group: "collections",
|
|
||||||
inputs: vec![
|
|
||||||
ValueType::ListExact(vec![ValueType::List, ValueType::Integer]),
|
|
||||||
ValueType::ListExact(vec![ValueType::Map, ValueType::String]),
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
|
||||||
let argument = argument.as_list()?;
|
|
||||||
|
|
||||||
let collection = &argument[0];
|
|
||||||
let index = argument[1].as_int()?;
|
|
||||||
|
|
||||||
if let Ok(list) = collection.as_list() {
|
|
||||||
if let Some(value) = list.get(index as usize) {
|
|
||||||
return Ok(value.clone());
|
|
||||||
} else {
|
|
||||||
return Ok(Value::Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Insert;
|
pub struct Insert;
|
||||||
@ -213,7 +184,10 @@ impl Tool for Insert {
|
|||||||
identifier: "insert",
|
identifier: "insert",
|
||||||
description: "Add new rows to a table.",
|
description: "Add new rows to a table.",
|
||||||
group: "collections",
|
group: "collections",
|
||||||
inputs: vec![ValueType::Table, ValueType::List],
|
inputs: vec![ValueType::ListExact(vec![
|
||||||
|
ValueType::Table,
|
||||||
|
ValueType::ListOf(Box::new(ValueType::List)),
|
||||||
|
])],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,76 +325,34 @@ impl Tool for Where {
|
|||||||
identifier: "where",
|
identifier: "where",
|
||||||
description: "Keep rows matching a predicate.",
|
description: "Keep rows matching a predicate.",
|
||||||
group: "collections",
|
group: "collections",
|
||||||
inputs: vec![],
|
inputs: vec![ValueType::ListExact(vec![
|
||||||
|
ValueType::Table,
|
||||||
|
ValueType::Function,
|
||||||
|
])],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, argument: &Value) -> Result<Value> {
|
fn run(&self, argument: &Value) -> Result<Value> {
|
||||||
let argument_list = argument.as_list()?;
|
let argument = self.check_type(argument)?.as_list()?;
|
||||||
Error::expect_function_argument_amount(self.info().identifier, argument_list.len(), 2)?;
|
let table = &argument[0].as_table()?;
|
||||||
|
let function = argument[1].as_function()?;
|
||||||
|
|
||||||
let collection = &argument_list[0];
|
let mut context = VariableMap::new();
|
||||||
let function = argument_list[1].as_function()?;
|
let mut new_table = Table::new(table.column_names().clone());
|
||||||
|
|
||||||
if let Ok(list) = collection.as_list() {
|
for row in table.rows() {
|
||||||
let mut context = VariableMap::new();
|
for (column_index, cell) in row.iter().enumerate() {
|
||||||
let mut new_list = Vec::new();
|
let column_name = table.column_names().get(column_index).unwrap();
|
||||||
|
|
||||||
for value in list {
|
context.set_value(column_name, cell.clone())?;
|
||||||
context.set_value("input", value.clone())?;
|
|
||||||
let keep_row = function.run_with_context(&mut context)?.as_boolean()?;
|
|
||||||
|
|
||||||
if keep_row {
|
|
||||||
new_list.push(value.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
let keep_row = function.run_with_context(&mut context)?.as_boolean()?;
|
||||||
|
|
||||||
return Ok(Value::List(new_list));
|
if keep_row {
|
||||||
|
new_table.insert(row.clone())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(map) = collection.as_map() {
|
Ok(Value::Table(new_table))
|
||||||
let mut context = VariableMap::new();
|
|
||||||
let mut new_map = VariableMap::new();
|
|
||||||
|
|
||||||
for (key, value) in map.inner() {
|
|
||||||
if let Ok(map) = value.as_map() {
|
|
||||||
for (key, value) in map.inner() {
|
|
||||||
context.set_value(key, value.clone())?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
context.set_value("input", value.clone())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let keep_row = function.run_with_context(&mut context)?.as_boolean()?;
|
|
||||||
|
|
||||||
if keep_row {
|
|
||||||
new_map.set_value(key, value.clone())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(Value::Map(new_map));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(table) = collection.as_table() {
|
|
||||||
let mut context = VariableMap::new();
|
|
||||||
let mut new_table = Table::new(table.column_names().clone());
|
|
||||||
|
|
||||||
for row in table.rows() {
|
|
||||||
for (column_index, cell) in row.iter().enumerate() {
|
|
||||||
let column_name = table.column_names().get(column_index).unwrap();
|
|
||||||
|
|
||||||
context.set_value(column_name, cell.clone())?;
|
|
||||||
}
|
|
||||||
let keep_row = function.run_with_context(&mut context)?.as_boolean()?;
|
|
||||||
|
|
||||||
if keep_row {
|
|
||||||
new_table.insert(row.clone())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(Value::Table(new_table));
|
|
||||||
}
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,10 +51,9 @@ pub mod time;
|
|||||||
/// Master list of all tools.
|
/// Master list of all tools.
|
||||||
///
|
///
|
||||||
/// This list is used to match identifiers with tools and to provide info to the shell.
|
/// This list is used to match identifiers with tools and to provide info to the shell.
|
||||||
pub const TOOL_LIST: [&'static dyn Tool; 57] = [
|
pub const TOOL_LIST: [&'static dyn Tool; 56] = [
|
||||||
&collections::Count,
|
&collections::Count,
|
||||||
&collections::CreateTable,
|
&collections::CreateTable,
|
||||||
&collections::Get,
|
|
||||||
&collections::Insert,
|
&collections::Insert,
|
||||||
&collections::Rows,
|
&collections::Rows,
|
||||||
&collections::Select,
|
&collections::Select,
|
||||||
|
Loading…
Reference in New Issue
Block a user