1
0
dust/src/abstract_tree/index.rs

119 lines
3.4 KiB
Rust
Raw Normal View History

2023-10-29 23:31:06 +00:00
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
2023-11-30 05:57:15 +00:00
use crate::{AbstractTree, Error, Expression, List, Map, Result, TypeDefinition, Value};
2023-10-29 23:31:06 +00:00
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Index {
2023-11-15 01:41:57 +00:00
pub collection: Expression,
pub index: Expression,
pub index_end: Option<Expression>,
2023-10-29 23:31:06 +00:00
}
impl AbstractTree for Index {
2023-11-30 03:54:46 +00:00
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
2023-10-29 23:31:06 +00:00
let collection_node = node.child(0).unwrap();
2023-11-30 03:54:46 +00:00
let collection = Expression::from_syntax_node(source, collection_node, context)?;
2023-10-29 23:31:06 +00:00
let index_node = node.child(2).unwrap();
2023-11-30 03:54:46 +00:00
let index = Expression::from_syntax_node(source, index_node, context)?;
2023-10-29 23:31:06 +00:00
let index_end_node = node.child(4);
2023-10-29 23:31:06 +00:00
let index_end = if let Some(index_end_node) = index_end_node {
2023-11-30 03:54:46 +00:00
Some(Expression::from_syntax_node(
source,
index_end_node,
context,
)?)
2023-10-29 23:31:06 +00:00
} else {
None
};
Ok(Index {
collection,
index,
index_end,
})
}
2023-11-30 00:23:42 +00:00
fn run(&self, source: &str, context: &Map) -> Result<Value> {
2023-11-15 01:00:57 +00:00
let collection = self.collection.run(source, context)?;
2023-10-29 23:31:06 +00:00
2023-11-15 01:00:57 +00:00
match collection {
2023-10-29 23:31:06 +00:00
Value::List(list) => {
let index = self.index.run(source, context)?.as_integer()? as usize;
let item = if let Some(index_end) = &self.index_end {
let index_end = index_end.run(source, context)?.as_integer()? as usize;
let sublist = list.items()[index..=index_end].to_vec();
Value::List(List::with_items(sublist))
} else {
list.items().get(index).cloned().unwrap_or_default()
};
Ok(item)
}
2023-11-15 01:41:57 +00:00
Value::Map(map) => {
2023-11-10 21:24:19 +00:00
let value = if let Expression::Identifier(identifier) = &self.index {
let key = identifier.inner();
map.variables()?.get(key).cloned().unwrap_or(Value::Empty)
} else {
2023-11-15 01:00:57 +00:00
let value = self.index.run(source, context)?;
2023-11-10 21:24:19 +00:00
let key = value.as_string()?;
map.variables()?.get(key).cloned().unwrap_or(Value::Empty)
};
2023-10-29 23:31:06 +00:00
Ok(value)
2023-10-29 23:31:06 +00:00
}
Value::String(string) => {
let index = self.index.run(source, context)?.as_integer()? as usize;
let item = string.chars().nth(index).unwrap_or_default();
Ok(Value::String(item.to_string()))
}
2023-11-15 01:00:57 +00:00
_ => Err(Error::ExpectedCollection { actual: collection }),
2023-10-29 23:31:06 +00:00
}
}
2023-11-30 00:23:42 +00:00
2023-11-30 05:57:15 +00:00
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> {
2023-11-30 00:23:42 +00:00
self.collection.expected_type(context)
}
2023-10-29 23:31:06 +00:00
}
2023-11-10 21:24:19 +00:00
#[cfg(test)]
mod tests {
use super::*;
use crate::evaluate;
#[test]
2023-11-30 14:30:25 +00:00
fn list_index() {
2023-11-10 21:24:19 +00:00
let test = evaluate("x = [1 [2] 3] x:1:0").unwrap();
assert_eq!(Value::Integer(2), test);
}
#[test]
2023-11-30 14:30:25 +00:00
fn map_index() {
2023-11-28 16:01:38 +00:00
let test = evaluate("x = {y = {z = 2}} x:y:z").unwrap();
2023-11-10 21:24:19 +00:00
assert_eq!(Value::Integer(2), test);
}
#[test]
2023-11-30 14:30:25 +00:00
fn complex_index() {
let test = evaluate(
"
x = [1 2 3]
y <fn -> int> || { 0 }
x:((y))
",
)
.unwrap();
2023-11-10 21:24:19 +00:00
assert_eq!(Value::Integer(1), test);
}
}