Add reference counting for list values
This commit is contained in:
parent
a5390c5150
commit
25778cc480
@ -1,7 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Expression, Identifier, Item, Map, Result, Value};
|
use crate::{AbstractTree, Expression, Identifier, Item, List, Map, Result, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Filter {
|
pub struct Filter {
|
||||||
@ -30,21 +30,23 @@ impl AbstractTree for Filter {
|
|||||||
|
|
||||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||||
let value = self.expression.run(source, context)?;
|
let value = self.expression.run(source, context)?;
|
||||||
let list = value.as_list()?;
|
let values = value.as_list()?.items();
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
let mut context = context.clone();
|
let mut context = context.clone();
|
||||||
let mut new_list = Vec::with_capacity(list.len());
|
let mut new_values = Vec::with_capacity(values.len());
|
||||||
|
|
||||||
for value in list {
|
for value in values.iter() {
|
||||||
context.set_value(key.clone(), value.clone())?;
|
context.set_value(key.clone(), value.clone())?;
|
||||||
|
|
||||||
let should_include = self.item.run(source, &mut context)?.as_boolean()?;
|
let should_include = self.item.run(source, &mut context)?.as_boolean()?;
|
||||||
|
|
||||||
if should_include {
|
if should_include {
|
||||||
new_list.push(value.clone());
|
new_values.push(value.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::List(new_list))
|
let list = List::with_items(new_values);
|
||||||
|
|
||||||
|
Ok(Value::List(list))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,11 @@ impl AbstractTree for Find {
|
|||||||
|
|
||||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||||
let value = self.expression.run(source, context)?;
|
let value = self.expression.run(source, context)?;
|
||||||
let list = value.as_list()?;
|
let values = value.as_list()?.items();
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
let mut context = context.clone();
|
let mut context = context.clone();
|
||||||
|
|
||||||
for value in list {
|
for value in values.iter() {
|
||||||
context.set_value(key.clone(), value.clone())?;
|
context.set_value(key.clone(), value.clone())?;
|
||||||
|
|
||||||
let should_return = self.item.run(source, &mut context)?.as_boolean()?;
|
let should_return = self.item.run(source, &mut context)?.as_boolean()?;
|
||||||
|
@ -29,13 +29,13 @@ impl AbstractTree for For {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||||
let value = self.expression.run(source, context)?;
|
let expression_run = self.expression.run(source, context)?;
|
||||||
let list = value.as_list()?;
|
let values = expression_run.as_list()?.items();
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
|
|
||||||
let original_value = context.get_value(key)?;
|
let original_value = context.get_value(key)?;
|
||||||
|
|
||||||
for value in list {
|
for value in values.iter() {
|
||||||
context.set_value(key.clone(), value.clone())?;
|
context.set_value(key.clone(), value.clone())?;
|
||||||
|
|
||||||
self.item.run(source, context)?;
|
self.item.run(source, context)?;
|
||||||
|
@ -26,13 +26,13 @@ impl AbstractTree for Insert {
|
|||||||
let table_name = self.identifier.inner().clone();
|
let table_name = self.identifier.inner().clone();
|
||||||
let mut table = self.identifier.run(source, context)?.as_table()?.clone();
|
let mut table = self.identifier.run(source, context)?.as_table()?.clone();
|
||||||
let new_rows = self.expression.run(source, context)?.into_inner_list()?;
|
let new_rows = self.expression.run(source, context)?.into_inner_list()?;
|
||||||
|
let values = new_rows.items();
|
||||||
|
|
||||||
table.reserve(new_rows.len());
|
table.reserve(values.len());
|
||||||
|
|
||||||
println!("{new_rows:?}");
|
for row in values.iter() {
|
||||||
|
let row_values = row.clone().into_inner_list()?;
|
||||||
for row in new_rows {
|
table.insert(row_values.items().clone())?;
|
||||||
table.insert(row.into_inner_list()?)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.set_value(table_name, Value::Table(table))?;
|
context.set_value(table_name, Value::Table(table))?;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Expression, Identifier, Item, Map, Result, Value};
|
use crate::{AbstractTree, Expression, Identifier, Item, List, Map, Result, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Remove {
|
pub struct Remove {
|
||||||
@ -29,30 +29,34 @@ impl AbstractTree for Remove {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||||
let value = self.expression.run(source, context)?;
|
let expression_run = self.expression.run(source, context)?;
|
||||||
let mut list = value.into_inner_list()?;
|
let values = expression_run.into_inner_list()?;
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
let mut sub_context = context.clone();
|
let mut sub_context = context.clone();
|
||||||
|
let mut should_remove_index = None;
|
||||||
|
|
||||||
for (index, value) in list.clone().iter().enumerate() {
|
for (index, value) in values.items().iter().enumerate() {
|
||||||
sub_context.set_value(key.clone(), value.clone())?;
|
sub_context.set_value(key.clone(), value.clone())?;
|
||||||
|
|
||||||
let should_remove = self.item.run(source, &mut sub_context)?.as_boolean()?;
|
let should_remove = self.item.run(source, &mut sub_context)?.as_boolean()?;
|
||||||
|
|
||||||
if should_remove {
|
if should_remove {
|
||||||
list.remove(index);
|
should_remove_index = Some(index);
|
||||||
|
|
||||||
match &self.expression {
|
match &self.expression {
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
context.set_value(identifier.inner().clone(), Value::List(list))?;
|
context
|
||||||
|
.set_value(identifier.inner().clone(), Value::List(values.clone()))?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(value.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::Empty)
|
if let Some(index) = should_remove_index {
|
||||||
|
Ok(values.items_mut().remove(index))
|
||||||
|
} else {
|
||||||
|
Ok(Value::Empty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use reqwest::blocking::get;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Error, Expression, Map, Result, Table, Value, ValueType};
|
use crate::{AbstractTree, Error, Expression, List, Map, Result, Table, Value, ValueType};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Tool {
|
pub enum Tool {
|
||||||
@ -287,7 +287,7 @@ impl AbstractTree for Tool {
|
|||||||
Ok(Value::String(data))
|
Ok(Value::String(data))
|
||||||
}
|
}
|
||||||
Tool::Length(expression) => {
|
Tool::Length(expression) => {
|
||||||
let length = expression.run(source, context)?.as_list()?.len();
|
let length = expression.run(source, context)?.as_list()?.items().len();
|
||||||
|
|
||||||
Ok(Value::Integer(length as i64))
|
Ok(Value::Integer(length as i64))
|
||||||
}
|
}
|
||||||
@ -399,7 +399,7 @@ impl AbstractTree for Tool {
|
|||||||
contents.push(Value::String(file_path));
|
contents.push(Value::String(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::List(contents)
|
Value::List(List::with_items(contents))
|
||||||
} else {
|
} else {
|
||||||
Value::String(read_to_string(path)?)
|
Value::String(read_to_string(path)?)
|
||||||
};
|
};
|
||||||
@ -517,7 +517,7 @@ impl AbstractTree for Tool {
|
|||||||
Tool::Random(expressions) => {
|
Tool::Random(expressions) => {
|
||||||
if expressions.len() == 1 {
|
if expressions.len() == 1 {
|
||||||
let value = expressions[0].run(source, context)?;
|
let value = expressions[0].run(source, context)?;
|
||||||
let list = value.as_list()?;
|
let list = value.as_list()?.items();
|
||||||
|
|
||||||
if list.len() < 2 {
|
if list.len() < 2 {
|
||||||
return Err(Error::ExpectedMinLengthList {
|
return Err(Error::ExpectedMinLengthList {
|
||||||
@ -555,7 +555,7 @@ impl AbstractTree for Tool {
|
|||||||
.map(|column_name| Value::String(column_name))
|
.map(|column_name| Value::String(column_name))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(Value::List(column_names))
|
Ok(Value::List(List::with_items(column_names)))
|
||||||
}
|
}
|
||||||
Tool::Rows(expression) => {
|
Tool::Rows(expression) => {
|
||||||
let rows = expression
|
let rows = expression
|
||||||
@ -564,10 +564,10 @@ impl AbstractTree for Tool {
|
|||||||
.rows()
|
.rows()
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|row| Value::List(row))
|
.map(|row| Value::List(List::with_items(row)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(Value::List(rows))
|
Ok(Value::List(List::with_items(rows)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use rayon::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Expression, Identifier, Item, Map, Result, Value};
|
use crate::{AbstractTree, Expression, Identifier, Item, List, Map, Result, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
@ -29,19 +30,29 @@ impl AbstractTree for Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||||
let value = self.expression.run(source, context)?;
|
let expression_run = self.expression.run(source, context)?;
|
||||||
let list = value.as_list()?;
|
let values = expression_run.as_list()?.items();
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
let mut context = context.clone();
|
let context = context.clone();
|
||||||
let mut new_list = Vec::with_capacity(list.len());
|
let new_list = List::with_capacity(values.len());
|
||||||
|
|
||||||
for value in list {
|
values.par_iter().try_for_each_with(
|
||||||
context.set_value(key.clone(), value.clone())?;
|
(context, new_list.clone()),
|
||||||
|
|(context, new_list), value| {
|
||||||
|
context.set_value(key.clone(), value.clone()).unwrap();
|
||||||
|
|
||||||
let value = self.item.run(source, &mut context)?;
|
let item_run = self.item.run(source, context);
|
||||||
|
|
||||||
new_list.push(value);
|
match item_run {
|
||||||
}
|
Ok(value) => {
|
||||||
|
new_list.items_mut().push(value);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Value::List(new_list))
|
Ok(Value::List(new_list))
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractTree, Error, Expression, Function, Identifier, Item, Map, Result, Table, Value,
|
AbstractTree, Error, Expression, Function, Identifier, Item, List, Map, Result, Table, Value,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ impl AbstractTree for ValueNode {
|
|||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::List(values)
|
Value::List(List::with_items(values))
|
||||||
}
|
}
|
||||||
ValueType::Empty => Value::Empty,
|
ValueType::Empty => Value::Empty,
|
||||||
ValueType::Map(nodes) => {
|
ValueType::Map(nodes) => {
|
||||||
@ -185,10 +185,10 @@ impl AbstractTree for ValueNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _row_values = row_expression.run(source, context)?;
|
let _row_values = row_expression.run(source, context)?;
|
||||||
let row_values = _row_values.as_list()?;
|
let row_values = _row_values.as_list()?.items();
|
||||||
|
|
||||||
for value in row_values {
|
for value in row_values.iter() {
|
||||||
let row = value.as_list()?.clone();
|
let row = value.as_list()?.items().clone();
|
||||||
|
|
||||||
rows.push(row)
|
rows.push(row)
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ pub fn evaluate(source: &str) -> Result<Value> {
|
|||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use dust_lang::*;
|
/// # use dust_lang::*;
|
||||||
/// let mut context = VariableMap::new();
|
/// let mut context = Map::new();
|
||||||
///
|
///
|
||||||
/// context.set_value("one".into(), 1.into());
|
/// context.set_value("one".into(), 1.into());
|
||||||
/// context.set_value("two".into(), 2.into());
|
/// context.set_value("two".into(), 2.into());
|
||||||
@ -96,7 +96,7 @@ impl<'context, 'code> Evaluator<'context, 'code> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::Table;
|
use crate::{List, Table};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -137,11 +137,11 @@ mod tests {
|
|||||||
fn evaluate_list() {
|
fn evaluate_list() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
evaluate("[1, 2, 'foobar']"),
|
evaluate("[1, 2, 'foobar']"),
|
||||||
Ok(Value::List(vec![
|
Ok(Value::List(List::with_items(vec![
|
||||||
Value::Integer(1),
|
Value::Integer(1),
|
||||||
Value::Integer(2),
|
Value::Integer(2),
|
||||||
Value::String("foobar".to_string()),
|
Value::String("foobar".to_string()),
|
||||||
]))
|
])))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ pub use crate::{
|
|||||||
abstract_tree::*,
|
abstract_tree::*,
|
||||||
error::*,
|
error::*,
|
||||||
evaluator::*,
|
evaluator::*,
|
||||||
value::{function::Function, map::Map, table::Table, value_type::ValueType, Value},
|
value::{function::Function, list::List, map::Map, table::Table, value_type::ValueType, Value},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod abstract_tree;
|
mod abstract_tree;
|
||||||
|
60
src/value/list.rs
Normal file
60
src/value/list.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
|
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Value;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct List(Arc<RwLock<Vec<Value>>>);
|
||||||
|
|
||||||
|
impl List {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
List(Arc::new(RwLock::new(Vec::new())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
|
List(Arc::new(RwLock::new(Vec::with_capacity(capacity))))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_items(items: Vec<Value>) -> Self {
|
||||||
|
List(Arc::new(RwLock::new(items)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn items(&self) -> RwLockReadGuard<'_, Vec<Value>> {
|
||||||
|
self.0.read().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn items_mut(&self) -> RwLockWriteGuard<'_, Vec<Value>> {
|
||||||
|
self.0.write().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for List {}
|
||||||
|
|
||||||
|
impl PartialEq for List {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
let left = self.0.read().unwrap().clone().into_iter();
|
||||||
|
let right = other.0.read().unwrap().clone().into_iter();
|
||||||
|
|
||||||
|
left.eq(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for List {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
let left = self.0.read().unwrap().clone().into_iter();
|
||||||
|
let right = other.0.read().unwrap().clone().into_iter();
|
||||||
|
|
||||||
|
left.cmp(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for List {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
let left = self.0.read().unwrap().clone().into_iter();
|
||||||
|
let right = other.0.read().unwrap().clone().into_iter();
|
||||||
|
|
||||||
|
left.partial_cmp(right)
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
sync::{Arc, RwLock, RwLockReadGuard},
|
sync::{Arc, RwLock, RwLockReadGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{value::Value, Error, Result, Table};
|
use crate::{value::Value, Error, List, Result, Table};
|
||||||
|
|
||||||
/// A collection dust variables comprised of key-value pairs.
|
/// A collection dust variables comprised of key-value pairs.
|
||||||
///
|
///
|
||||||
@ -53,7 +53,7 @@ impl Map {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(list.get(index).cloned())
|
Ok(list.items().get(index).cloned())
|
||||||
} else if let Value::Map(map) = value {
|
} else if let Value::Map(map) = value {
|
||||||
map.get_value(next_identifier)
|
map.get_value(next_identifier)
|
||||||
} else {
|
} else {
|
||||||
@ -83,10 +83,11 @@ impl Map {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut missing_elements = index.saturating_sub(list.len()) + 1;
|
let mut missing_elements = index.saturating_sub(list.items().len()) + 1;
|
||||||
|
let mut items = list.items_mut();
|
||||||
|
|
||||||
while missing_elements > 0 {
|
while missing_elements > 0 {
|
||||||
list.push(value.clone());
|
items.push(value.clone());
|
||||||
|
|
||||||
missing_elements -= 1;
|
missing_elements -= 1;
|
||||||
}
|
}
|
||||||
@ -197,8 +198,11 @@ impl From<&Table> for Map {
|
|||||||
let mut map = Map::new();
|
let mut map = Map::new();
|
||||||
|
|
||||||
for (row_index, row) in value.rows().iter().enumerate() {
|
for (row_index, row) in value.rows().iter().enumerate() {
|
||||||
map.set_value(row_index.to_string(), Value::List(row.clone()))
|
map.set_value(
|
||||||
.unwrap();
|
row_index.to_string(),
|
||||||
|
Value::List(List::with_items(row.clone())),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
map
|
map
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Types that represent runtime values.
|
//! Types that represent runtime values.
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
Function, Map, Table, ValueType,
|
Function, List, Map, Table, ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
@ -20,6 +20,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub mod function;
|
pub mod function;
|
||||||
|
pub mod list;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
pub mod value_type;
|
pub mod value_type;
|
||||||
@ -31,7 +32,7 @@ pub mod value_type;
|
|||||||
/// value that can be treated as any other.
|
/// value that can be treated as any other.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
List(Vec<Value>),
|
List(List),
|
||||||
Map(Map),
|
Map(Map),
|
||||||
Table(Table),
|
Table(Table),
|
||||||
Function(Function),
|
Function(Function),
|
||||||
@ -141,7 +142,7 @@ impl Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
|
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
|
||||||
pub fn as_list(&self) -> Result<&Vec<Value>> {
|
pub fn as_list(&self) -> Result<&List> {
|
||||||
match self {
|
match self {
|
||||||
Value::List(list) => Ok(list),
|
Value::List(list) => Ok(list),
|
||||||
value => Err(Error::ExpectedList {
|
value => Err(Error::ExpectedList {
|
||||||
@ -151,7 +152,7 @@ impl Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
|
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
|
||||||
pub fn into_inner_list(self) -> Result<Vec<Value>> {
|
pub fn into_inner_list(self) -> Result<List> {
|
||||||
match self {
|
match self {
|
||||||
Value::List(list) => Ok(list),
|
Value::List(list) => Ok(list),
|
||||||
value => Err(Error::ExpectedList {
|
value => Err(Error::ExpectedList {
|
||||||
@ -321,7 +322,7 @@ impl AddAssign for Value {
|
|||||||
(Value::Float(left), Value::Float(right)) => *left += right,
|
(Value::Float(left), Value::Float(right)) => *left += right,
|
||||||
(Value::Float(left), Value::Integer(right)) => *left += right as f64,
|
(Value::Float(left), Value::Integer(right)) => *left += right as f64,
|
||||||
(Value::String(left), Value::String(right)) => *left += &right,
|
(Value::String(left), Value::String(right)) => *left += &right,
|
||||||
(Value::List(list), value) => list.push(value),
|
(Value::List(list), value) => list.items_mut().push(value),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,9 +400,10 @@ impl Serialize for Value {
|
|||||||
Value::Integer(inner) => serializer.serialize_i64(*inner),
|
Value::Integer(inner) => serializer.serialize_i64(*inner),
|
||||||
Value::Boolean(inner) => serializer.serialize_bool(*inner),
|
Value::Boolean(inner) => serializer.serialize_bool(*inner),
|
||||||
Value::List(inner) => {
|
Value::List(inner) => {
|
||||||
let mut list = serializer.serialize_tuple(inner.len())?;
|
let items = inner.items();
|
||||||
|
let mut list = serializer.serialize_tuple(items.len())?;
|
||||||
|
|
||||||
for value in inner {
|
for value in items.iter() {
|
||||||
list.serialize_element(value)?;
|
list.serialize_element(value)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +427,7 @@ impl Display for Value {
|
|||||||
Value::Empty => write!(f, "empty"),
|
Value::Empty => write!(f, "empty"),
|
||||||
Value::List(list) => {
|
Value::List(list) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
for value in list {
|
for value in list.items().iter() {
|
||||||
write!(f, " {value} ")?;
|
write!(f, " {value} ")?;
|
||||||
}
|
}
|
||||||
write!(f, "]")
|
write!(f, "]")
|
||||||
@ -469,7 +471,7 @@ impl From<bool> for Value {
|
|||||||
|
|
||||||
impl From<Vec<Value>> for Value {
|
impl From<Vec<Value>> for Value {
|
||||||
fn from(vec: Vec<Value>) -> Self {
|
fn from(vec: Vec<Value>) -> Self {
|
||||||
Value::List(vec)
|
Value::List(List::with_items(vec))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,15 +511,15 @@ impl TryFrom<JsonValue> for Value {
|
|||||||
Ok(Value::Map(map))
|
Ok(Value::Map(map))
|
||||||
}
|
}
|
||||||
Array(array) => {
|
Array(array) => {
|
||||||
let mut list = Vec::new();
|
let mut values = Vec::new();
|
||||||
|
|
||||||
for json_value in array {
|
for json_value in array {
|
||||||
let value = Value::try_from(json_value)?;
|
let value = Value::try_from(json_value)?;
|
||||||
|
|
||||||
list.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::List(list))
|
Ok(Value::List(List::with_items(values)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,15 +549,15 @@ impl TryFrom<&JsonValue> for Value {
|
|||||||
Ok(Value::Map(map))
|
Ok(Value::Map(map))
|
||||||
}
|
}
|
||||||
Array(array) => {
|
Array(array) => {
|
||||||
let mut list = Vec::new();
|
let mut values = Vec::new();
|
||||||
|
|
||||||
for json_value in array {
|
for json_value in array {
|
||||||
let value = Value::try_from(json_value)?;
|
let value = Value::try_from(json_value)?;
|
||||||
|
|
||||||
list.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::List(list))
|
Ok(Value::List(List::with_items(values)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -822,7 +824,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
|
|||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::List(list))
|
Ok(Value::List(List::with_items(list)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<M>(self, mut access: M) -> std::result::Result<Value, M::Error>
|
fn visit_map<M>(self, mut access: M) -> std::result::Result<Value, M::Error>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Error, Map, Result, Value};
|
use crate::{Error, List, Map, Result, Value};
|
||||||
use comfy_table::{Cell, Color, ContentArrangement, Table as ComfyTable};
|
use comfy_table::{Cell, Color, ContentArrangement, Table as ComfyTable};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
@ -146,7 +146,7 @@ impl Display for Table {
|
|||||||
Value::List(list) => {
|
Value::List(list) => {
|
||||||
let mut string = "(".to_string();
|
let mut string = "(".to_string();
|
||||||
|
|
||||||
for (index, value) in list.into_iter().enumerate() {
|
for (index, value) in list.items().iter().enumerate() {
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
string.push_str(", ");
|
string.push_str(", ");
|
||||||
}
|
}
|
||||||
@ -248,11 +248,11 @@ impl From<&Value> for Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Vec<Value>> for Table {
|
impl From<&List> for Table {
|
||||||
fn from(list: &Vec<Value>) -> Self {
|
fn from(list: &List) -> Self {
|
||||||
let mut table = Table::new(vec!["index".to_string(), "item".to_string()]);
|
let mut table = Table::new(vec!["index".to_string(), "item".to_string()]);
|
||||||
|
|
||||||
for (i, value) in list.iter().enumerate() {
|
for (i, value) in list.items().iter().enumerate() {
|
||||||
table
|
table
|
||||||
.insert(vec![Value::Integer(i as i64), value.clone()])
|
.insert(vec![Value::Integer(i as i64), value.clone()])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -262,13 +262,13 @@ impl From<&Vec<Value>> for Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&mut Vec<Value>> for Table {
|
impl From<&mut List> for Table {
|
||||||
fn from(list: &mut Vec<Value>) -> Self {
|
fn from(list: &mut List) -> Self {
|
||||||
let mut table = Table::new(vec!["index".to_string(), "item".to_string()]);
|
let mut table = Table::new(vec!["index".to_string(), "item".to_string()]);
|
||||||
|
|
||||||
for (i, value) in list.iter().enumerate() {
|
for (i, value) in list.items().iter().enumerate() {
|
||||||
if let Ok(list) = value.as_list() {
|
if let Ok(list) = value.as_list() {
|
||||||
table.insert(list.clone()).unwrap();
|
table.insert(list.items().clone()).unwrap();
|
||||||
} else {
|
} else {
|
||||||
table
|
table
|
||||||
.insert(vec![Value::Integer(i as i64), value.clone()])
|
.insert(vec![Value::Integer(i as i64), value.clone()])
|
||||||
|
@ -104,6 +104,7 @@ impl From<&Value> for ValueType {
|
|||||||
Value::Empty => ValueType::Empty,
|
Value::Empty => ValueType::Empty,
|
||||||
Value::List(list) => {
|
Value::List(list) => {
|
||||||
let value_nodes = list
|
let value_nodes = list
|
||||||
|
.items()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|value| Expression::Value(ValueNode::new(value.value_type(), 0, 0)))
|
.map(|value| Expression::Value(ValueNode::new(value.value_type(), 0, 0)))
|
||||||
.collect();
|
.collect();
|
||||||
|
Loading…
Reference in New Issue
Block a user