Change string type to be passed by reference
This commit is contained in:
parent
525c87bf0f
commit
20e0ec0e3d
@ -43,7 +43,7 @@ impl BuiltInValue {
|
||||
fn get(&self) -> &Value {
|
||||
match self {
|
||||
BuiltInValue::Args => ARGS.get_or_init(|| {
|
||||
let args = args().map(|arg| Value::String(arg.to_string())).collect();
|
||||
let args = args().map(|arg| Value::string(arg.to_string())).collect();
|
||||
|
||||
Value::List(List::with_items(args))
|
||||
}),
|
||||
|
@ -72,7 +72,7 @@ impl AbstractTree for Index {
|
||||
let key = value.as_string()?;
|
||||
|
||||
map.variables()?
|
||||
.get(key)
|
||||
.get(key.as_str())
|
||||
.map(|(value, _)| value.clone())
|
||||
.unwrap_or_default()
|
||||
};
|
||||
@ -81,9 +81,9 @@ impl AbstractTree for Index {
|
||||
}
|
||||
Value::String(string) => {
|
||||
let index = self.index.run(source, context)?.as_integer()? as usize;
|
||||
let item = string.chars().nth(index).unwrap_or_default();
|
||||
let item = string.read()?.chars().nth(index).unwrap_or_default();
|
||||
|
||||
Ok(Value::String(item.to_string()))
|
||||
Ok(Value::string(item.to_string()))
|
||||
}
|
||||
_ => Err(Error::ExpectedCollection { actual: collection }),
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ impl AbstractTree for ValueNode {
|
||||
ValueNode::Float(value_source) => Value::Float(value_source.parse().unwrap()),
|
||||
ValueNode::Function(function) => Value::Function(function.clone()),
|
||||
ValueNode::Integer(value_source) => Value::Integer(value_source.parse().unwrap()),
|
||||
ValueNode::String(value_source) => Value::String(value_source.parse().unwrap()),
|
||||
ValueNode::String(value_source) => Value::string(value_source.clone()),
|
||||
ValueNode::List(expressions) => {
|
||||
let mut values = Vec::with_capacity(expressions.len());
|
||||
|
||||
|
@ -187,7 +187,7 @@ fn display_value(value: &Value, ui: &mut egui::Ui) {
|
||||
ui.label(function.to_string());
|
||||
}
|
||||
Value::String(string) => {
|
||||
ui.label(RichText::new(string).color(Color32::GREEN));
|
||||
ui.label(RichText::new(string.read().unwrap().as_str()).color(Color32::GREEN));
|
||||
}
|
||||
Value::Float(float) => {
|
||||
ui.label(float.to_string());
|
||||
|
@ -68,9 +68,9 @@ impl BuiltInFunction {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
|
||||
let path = arguments.first().unwrap().as_string()?;
|
||||
let file_content = read_to_string(path)?;
|
||||
let file_content = read_to_string(path.as_str())?;
|
||||
|
||||
Ok(Value::String(file_content))
|
||||
Ok(Value::string(file_content))
|
||||
}
|
||||
BuiltInFunction::JsonParse => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
@ -88,8 +88,8 @@ impl BuiltInFunction {
|
||||
list.items().len()
|
||||
} else if let Ok(map) = value.as_map() {
|
||||
map.variables()?.len()
|
||||
} else if let Ok(string) = value.as_string() {
|
||||
string.chars().count()
|
||||
} else if let Ok(str) = value.as_string() {
|
||||
str.chars().count()
|
||||
} else {
|
||||
return Err(Error::ExpectedCollection {
|
||||
actual: value.clone(),
|
||||
|
@ -12,10 +12,17 @@ pub enum StringFunction {
|
||||
AsBytes,
|
||||
EndsWith,
|
||||
Find,
|
||||
Insert,
|
||||
IsAscii,
|
||||
IsEmpty,
|
||||
Lines,
|
||||
Matches,
|
||||
Parse,
|
||||
Pop,
|
||||
Push,
|
||||
Remove,
|
||||
ReplaceRange,
|
||||
Retain,
|
||||
Split,
|
||||
SplitAt,
|
||||
SplitInclusive,
|
||||
@ -33,6 +40,7 @@ pub enum StringFunction {
|
||||
TrimMatches,
|
||||
TrimStart,
|
||||
TrimStartMatches,
|
||||
Truncate,
|
||||
}
|
||||
|
||||
impl StringFunction {
|
||||
@ -41,10 +49,17 @@ impl StringFunction {
|
||||
StringFunction::AsBytes => "as_bytes",
|
||||
StringFunction::EndsWith => "ends_with",
|
||||
StringFunction::Find => "find",
|
||||
StringFunction::Insert => "insert",
|
||||
StringFunction::IsAscii => "is_ascii",
|
||||
StringFunction::IsEmpty => "is_empty",
|
||||
StringFunction::Lines => "lines",
|
||||
StringFunction::Matches => "matches",
|
||||
StringFunction::Parse => "parse",
|
||||
StringFunction::Pop => "pop",
|
||||
StringFunction::Push => "push",
|
||||
StringFunction::Remove => "remove",
|
||||
StringFunction::ReplaceRange => "replace_range",
|
||||
StringFunction::Retain => "retain",
|
||||
StringFunction::Split => "split",
|
||||
StringFunction::SplitAt => "split_at",
|
||||
StringFunction::SplitInclusive => "split_inclusive",
|
||||
@ -62,6 +77,7 @@ impl StringFunction {
|
||||
StringFunction::TrimMatches => "trim_matches",
|
||||
StringFunction::TrimStart => "trim_start",
|
||||
StringFunction::TrimStartMatches => "trim_start_matches",
|
||||
StringFunction::Truncate => "truncate",
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,12 +93,33 @@ impl StringFunction {
|
||||
vec![Type::String, Type::String],
|
||||
Type::option(Type::Integer),
|
||||
),
|
||||
StringFunction::Insert => {
|
||||
Type::function(vec![Type::String, Type::Integer, Type::String], Type::None)
|
||||
}
|
||||
StringFunction::IsAscii => Type::function(vec![Type::String], Type::Boolean),
|
||||
StringFunction::IsEmpty => Type::function(vec![Type::String], Type::Boolean),
|
||||
StringFunction::Lines => Type::function(vec![Type::String], Type::list(Type::String)),
|
||||
StringFunction::Matches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::Parse => Type::function(vec![Type::String], Type::Any),
|
||||
StringFunction::Pop => Type::function(vec![], Type::option(Type::String)),
|
||||
StringFunction::Push => Type::function(vec![Type::String], Type::None),
|
||||
StringFunction::Remove => Type::function(
|
||||
vec![Type::String, Type::Integer],
|
||||
Type::option(Type::String),
|
||||
),
|
||||
StringFunction::ReplaceRange => Type::function(
|
||||
vec![Type::String, Type::list(Type::Integer), Type::String],
|
||||
Type::None,
|
||||
),
|
||||
StringFunction::Retain => Type::function(
|
||||
vec![
|
||||
Type::String,
|
||||
Type::function(vec![Type::String], Type::Boolean),
|
||||
],
|
||||
Type::None,
|
||||
),
|
||||
StringFunction::Split => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
@ -113,6 +150,9 @@ impl StringFunction {
|
||||
}
|
||||
StringFunction::ToLowercase => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::ToUppercase => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::Truncate => {
|
||||
Type::function(vec![Type::String, Type::Integer], Type::None)
|
||||
}
|
||||
StringFunction::Trim => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimEnd => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimEndMatches => {
|
||||
@ -145,7 +185,8 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
|
||||
Value::Boolean(string.ends_with(pattern))
|
||||
}
|
||||
@ -153,7 +194,8 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let find = string
|
||||
.find(pattern)
|
||||
.map(|index| Box::new(Value::Integer(index as i64)));
|
||||
@ -174,13 +216,24 @@ impl StringFunction {
|
||||
|
||||
Value::Boolean(string.is_empty())
|
||||
}
|
||||
StringFunction::Insert => {
|
||||
Error::expect_argument_amount(self.name(), 3, arguments.len())?;
|
||||
|
||||
let mut string = arguments.get(0).unwrap().as_string()?.to_string();
|
||||
let index = arguments.get(1).unwrap().as_integer()? as usize;
|
||||
let insertion = arguments.get(2).unwrap().as_string()?;
|
||||
|
||||
string.insert_str(index, &insertion);
|
||||
|
||||
Value::none()
|
||||
}
|
||||
StringFunction::Lines => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
|
||||
let string = arguments.first().unwrap().as_string()?;
|
||||
let lines = string
|
||||
.lines()
|
||||
.map(|line| Value::String(line.to_string()))
|
||||
.map(|line| Value::string(line.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(lines))
|
||||
@ -189,22 +242,58 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let matches = string
|
||||
.matches(pattern)
|
||||
.map(|pattern| Value::String(pattern.to_string()))
|
||||
.map(|pattern| Value::string(pattern.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(matches))
|
||||
}
|
||||
StringFunction::Parse => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
|
||||
let string = arguments.first().unwrap().as_string()?;
|
||||
|
||||
if let Ok(integer) = string.parse::<i64>() {
|
||||
Value::option(Some(Value::Integer(integer)))
|
||||
} else if let Ok(float) = string.parse::<f64>() {
|
||||
Value::option(Some(Value::Float(float)))
|
||||
} else {
|
||||
Value::none()
|
||||
}
|
||||
}
|
||||
StringFunction::Pop => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
|
||||
let mut string = arguments.first().unwrap().as_string_mut()?;
|
||||
let popped = string.pop().map(|char| Value::string(char.to_string()));
|
||||
|
||||
Value::option(popped)
|
||||
}
|
||||
StringFunction::Push => {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let mut string = arguments.get(0).unwrap().as_string_mut()?;
|
||||
let addition = arguments.get(1).unwrap().as_string()?;
|
||||
|
||||
string.push_str(&addition);
|
||||
|
||||
Value::none()
|
||||
}
|
||||
StringFunction::Remove => todo!(),
|
||||
StringFunction::ReplaceRange => todo!(),
|
||||
StringFunction::Retain => todo!(),
|
||||
StringFunction::Split => {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let sections = string
|
||||
.split(pattern)
|
||||
.map(|section| Value::String(section.to_string()))
|
||||
.map(|section| Value::string(section.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(sections))
|
||||
@ -217,18 +306,19 @@ impl StringFunction {
|
||||
let (left, right) = string.split_at(index as usize);
|
||||
|
||||
Value::List(List::with_items(vec![
|
||||
Value::String(left.to_string()),
|
||||
Value::String(right.to_string()),
|
||||
Value::string(left.to_string()),
|
||||
Value::string(right.to_string()),
|
||||
]))
|
||||
}
|
||||
StringFunction::SplitInclusive => {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let sections = string
|
||||
.split(pattern)
|
||||
.map(|pattern| Value::String(pattern.to_string()))
|
||||
.map(|pattern| Value::string(pattern.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(sections))
|
||||
@ -238,10 +328,11 @@ impl StringFunction {
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let count = arguments.get(1).unwrap().as_integer()?;
|
||||
let pattern = arguments.get(2).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(2).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let sections = string
|
||||
.splitn(count as usize, pattern)
|
||||
.map(|pattern| Value::String(pattern.to_string()))
|
||||
.map(|pattern| Value::string(pattern.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(sections))
|
||||
@ -250,11 +341,12 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let sections = string.split_once(pattern).map(|(left, right)| {
|
||||
Value::List(List::with_items(vec![
|
||||
Value::String(left.to_string()),
|
||||
Value::String(right.to_string()),
|
||||
Value::string(left.to_string()),
|
||||
Value::string(right.to_string()),
|
||||
]))
|
||||
});
|
||||
|
||||
@ -264,10 +356,11 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let sections = string
|
||||
.split_terminator(pattern)
|
||||
.map(|section| Value::String(section.to_string()))
|
||||
.map(|section| Value::string(section.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(sections))
|
||||
@ -278,7 +371,7 @@ impl StringFunction {
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let sections = string
|
||||
.split_whitespace()
|
||||
.map(|section| Value::String(section.to_string()))
|
||||
.map(|section| Value::string(section.to_string()))
|
||||
.collect();
|
||||
|
||||
Value::List(List::with_items(sections))
|
||||
@ -287,7 +380,8 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
|
||||
Value::Boolean(string.starts_with(pattern))
|
||||
}
|
||||
@ -295,10 +389,11 @@ impl StringFunction {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let prefix = arguments.get(1).unwrap().as_string()?;
|
||||
let prefix_string = arguments.get(1).unwrap().as_string()?;
|
||||
let prefix = prefix_string.as_str();
|
||||
let stripped = string
|
||||
.strip_prefix(prefix)
|
||||
.map(|remainder| Value::String(remainder.to_string()));
|
||||
.map(|remainder| Value::string(remainder.to_string()));
|
||||
|
||||
Value::option(stripped)
|
||||
}
|
||||
@ -308,7 +403,7 @@ impl StringFunction {
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let lowercase = string.to_lowercase();
|
||||
|
||||
Value::String(lowercase)
|
||||
Value::string(lowercase)
|
||||
}
|
||||
StringFunction::ToUppercase => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
@ -316,14 +411,14 @@ impl StringFunction {
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let uppercase = string.to_uppercase();
|
||||
|
||||
Value::String(uppercase)
|
||||
Value::string(uppercase)
|
||||
}
|
||||
StringFunction::Trim => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
|
||||
let trimmed = arguments.first().unwrap().as_string()?.trim().to_string();
|
||||
|
||||
Value::String(trimmed)
|
||||
Value::string(trimmed)
|
||||
}
|
||||
StringFunction::TrimEnd => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
@ -335,16 +430,17 @@ impl StringFunction {
|
||||
.trim_end()
|
||||
.to_string();
|
||||
|
||||
Value::String(trimmed)
|
||||
Value::string(trimmed)
|
||||
}
|
||||
StringFunction::TrimEndMatches => {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
|
||||
let string = arguments.get(0).unwrap().as_string()?;
|
||||
let pattern = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern_string = arguments.get(1).unwrap().as_string()?;
|
||||
let pattern = pattern_string.as_str();
|
||||
let trimmed = string.trim_end_matches(pattern).to_string();
|
||||
|
||||
Value::String(trimmed)
|
||||
Value::string(trimmed)
|
||||
}
|
||||
StringFunction::TrimMatches => {
|
||||
Error::expect_argument_amount(self.name(), 2, arguments.len())?;
|
||||
@ -358,7 +454,7 @@ impl StringFunction {
|
||||
.collect::<Vec<char>>();
|
||||
let trimmed = string.trim_matches(pattern.as_slice()).to_string();
|
||||
|
||||
Value::String(trimmed)
|
||||
Value::string(trimmed)
|
||||
}
|
||||
StringFunction::TrimStart => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
@ -370,9 +466,10 @@ impl StringFunction {
|
||||
.trim_start()
|
||||
.to_string();
|
||||
|
||||
Value::String(trimmed)
|
||||
Value::string(trimmed)
|
||||
}
|
||||
StringFunction::TrimStartMatches => todo!(),
|
||||
StringFunction::Truncate => todo!(),
|
||||
};
|
||||
|
||||
Ok(value)
|
||||
|
@ -57,7 +57,7 @@ fn main() {
|
||||
|
||||
if let Some(input) = args.input {
|
||||
context
|
||||
.set("input".to_string(), Value::String(input), None)
|
||||
.set("input".to_string(), Value::string(input), None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ fn main() {
|
||||
let file_contents = read_to_string(path).unwrap();
|
||||
|
||||
context
|
||||
.set("input".to_string(), Value::String(file_contents), None)
|
||||
.set("input".to_string(), Value::string(file_contents), None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ use std::{
|
||||
fmt::{self, Display, Formatter},
|
||||
marker::PhantomData,
|
||||
ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign},
|
||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
pub mod function;
|
||||
@ -32,7 +33,7 @@ pub enum Value {
|
||||
List(List),
|
||||
Map(Map),
|
||||
Function(Function),
|
||||
String(String),
|
||||
String(Arc<RwLock<String>>),
|
||||
Float(f64),
|
||||
Integer(i64),
|
||||
Boolean(bool),
|
||||
@ -46,6 +47,10 @@ impl Default for Value {
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn string(string: String) -> Self {
|
||||
Value::String(Arc::new(RwLock::new(string)))
|
||||
}
|
||||
|
||||
pub fn r#type(&self) -> Type {
|
||||
let r#type = match self {
|
||||
Value::List(list) => {
|
||||
@ -135,10 +140,20 @@ impl Value {
|
||||
matches!(self, Value::Map(_))
|
||||
}
|
||||
|
||||
/// Borrows the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`.
|
||||
pub fn as_string(&self) -> Result<&String> {
|
||||
/// Borrows the value stored in `self` as `&str`, or returns `Err` if `self` is not a `Value::String`.
|
||||
pub fn as_string(&self) -> Result<RwLockReadGuard<String>> {
|
||||
match self {
|
||||
Value::String(string) => Ok(string),
|
||||
Value::String(string) => Ok(string.read()?),
|
||||
value => Err(Error::ExpectedString {
|
||||
actual: value.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrows the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`.
|
||||
pub fn as_string_mut(&self) -> Result<RwLockWriteGuard<String>> {
|
||||
match self {
|
||||
Value::String(string) => Ok(string.write()?),
|
||||
value => Err(Error::ExpectedString {
|
||||
actual: value.clone(),
|
||||
}),
|
||||
@ -197,7 +212,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
|
||||
/// Takes ownership of 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<List> {
|
||||
match self {
|
||||
Value::List(list) => Ok(list),
|
||||
@ -276,11 +291,11 @@ impl Add for Value {
|
||||
}
|
||||
|
||||
if let (Ok(left), Ok(right)) = (self.as_string(), other.as_string()) {
|
||||
return Ok(Value::String(left.to_string() + right));
|
||||
return Ok(Value::string(left.to_string() + right.as_str()));
|
||||
}
|
||||
|
||||
if self.is_string() || other.is_string() {
|
||||
return Ok(Value::String(self.to_string() + &other.to_string()));
|
||||
return Ok(Value::string(self.to_string() + &other.to_string()));
|
||||
}
|
||||
|
||||
let non_number_or_string = if !self.is_number() == !self.is_string() {
|
||||
@ -368,7 +383,9 @@ impl AddAssign for Value {
|
||||
(Value::Integer(left), Value::Integer(right)) => *left += right,
|
||||
(Value::Float(left), Value::Float(right)) => *left += right,
|
||||
(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.write().unwrap() += right.read().unwrap().as_str()
|
||||
}
|
||||
(Value::List(list), value) => list.items_mut().push(value),
|
||||
_ => {}
|
||||
}
|
||||
@ -405,7 +422,9 @@ impl PartialEq for Value {
|
||||
(Value::Integer(left), Value::Integer(right)) => left == right,
|
||||
(Value::Float(left), Value::Float(right)) => left == right,
|
||||
(Value::Boolean(left), Value::Boolean(right)) => left == right,
|
||||
(Value::String(left), Value::String(right)) => left == right,
|
||||
(Value::String(left), Value::String(right)) => {
|
||||
left.read().unwrap().as_str() == right.read().unwrap().as_str()
|
||||
}
|
||||
(Value::List(left), Value::List(right)) => left == right,
|
||||
(Value::Map(left), Value::Map(right)) => left == right,
|
||||
(Value::Function(left), Value::Function(right)) => left == right,
|
||||
@ -424,7 +443,11 @@ impl PartialOrd for Value {
|
||||
impl Ord for Value {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match (self, other) {
|
||||
(Value::String(left), Value::String(right)) => left.cmp(right),
|
||||
(Value::String(left), Value::String(right)) => left
|
||||
.read()
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.cmp(right.read().unwrap().as_str()),
|
||||
(Value::String(_), _) => Ordering::Greater,
|
||||
(Value::Float(left), Value::Float(right)) => left.total_cmp(right),
|
||||
(Value::Integer(left), Value::Integer(right)) => left.cmp(right),
|
||||
@ -458,7 +481,7 @@ impl Serialize for Value {
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
Value::String(inner) => serializer.serialize_str(inner),
|
||||
Value::String(inner) => serializer.serialize_str(inner.read().unwrap().as_str()),
|
||||
Value::Float(inner) => serializer.serialize_f64(*inner),
|
||||
Value::Integer(inner) => serializer.serialize_i64(*inner),
|
||||
Value::Boolean(inner) => serializer.serialize_bool(*inner),
|
||||
@ -482,7 +505,7 @@ impl Serialize for Value {
|
||||
impl Display for Value {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Value::String(string) => write!(f, "{string}"),
|
||||
Value::String(string) => write!(f, "{}", string.read().unwrap()),
|
||||
Value::Float(float) => write!(f, "{float}"),
|
||||
Value::Integer(int) => write!(f, "{int}"),
|
||||
Value::Boolean(boolean) => write!(f, "{boolean}"),
|
||||
@ -502,13 +525,13 @@ impl Display for Value {
|
||||
|
||||
impl From<String> for Value {
|
||||
fn from(string: String) -> Self {
|
||||
Value::String(string)
|
||||
Value::string(string)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Value {
|
||||
fn from(string: &str) -> Self {
|
||||
Value::String(string.to_string())
|
||||
Value::string(string.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,8 +575,8 @@ impl TryFrom<Value> for String {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: Value) -> std::result::Result<Self, Self::Error> {
|
||||
if let Value::String(value) = value {
|
||||
Ok(value)
|
||||
if let Value::String(rw_lock) = value {
|
||||
Ok(rw_lock.read()?.to_string())
|
||||
} else {
|
||||
Err(Error::ExpectedString { actual: value })
|
||||
}
|
||||
@ -721,7 +744,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(Value::String(v.to_string()))
|
||||
Ok(Value::string(v.to_string()))
|
||||
}
|
||||
|
||||
fn visit_borrowed_str<E>(self, v: &'de str) -> std::result::Result<Self::Value, E>
|
||||
@ -735,7 +758,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(Value::String(v))
|
||||
Ok(Value::string(v))
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> std::result::Result<Self::Value, E>
|
||||
|
@ -115,14 +115,14 @@ mod value {
|
||||
|
||||
#[test]
|
||||
fn string() {
|
||||
assert_eq!(interpret("\"one\""), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(interpret("'one'"), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(interpret("`one`"), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(interpret("`'one'`"), Ok(Value::String("'one'".to_string())));
|
||||
assert_eq!(interpret("'`one`'"), Ok(Value::String("`one`".to_string())));
|
||||
assert_eq!(interpret("\"one\""), Ok(Value::string("one".to_string())));
|
||||
assert_eq!(interpret("'one'"), Ok(Value::string("one".to_string())));
|
||||
assert_eq!(interpret("`one`"), Ok(Value::string("one".to_string())));
|
||||
assert_eq!(interpret("`'one'`"), Ok(Value::string("'one'".to_string())));
|
||||
assert_eq!(interpret("'`one`'"), Ok(Value::string("`one`".to_string())));
|
||||
assert_eq!(
|
||||
interpret("\"'one'\""),
|
||||
Ok(Value::String("'one'".to_string()))
|
||||
Ok(Value::string("'one'".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ mod value {
|
||||
Ok(Value::List(List::with_items(vec![
|
||||
Value::Integer(1),
|
||||
Value::Integer(2),
|
||||
Value::String("foobar".to_string()),
|
||||
Value::string("foobar".to_string()),
|
||||
])))
|
||||
);
|
||||
}
|
||||
@ -143,7 +143,7 @@ mod value {
|
||||
let map = Map::new();
|
||||
|
||||
map.set("x".to_string(), Value::Integer(1), None).unwrap();
|
||||
map.set("foo".to_string(), Value::String("bar".to_string()), None)
|
||||
map.set("foo".to_string(), Value::string("bar".to_string()), None)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(interpret("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map)));
|
||||
@ -157,7 +157,7 @@ mod value {
|
||||
.unwrap();
|
||||
map.set(
|
||||
"foo".to_string(),
|
||||
Value::String("bar".to_string()),
|
||||
Value::string("bar".to_string()),
|
||||
Some(Type::String),
|
||||
)
|
||||
.unwrap();
|
||||
@ -228,7 +228,7 @@ mod function_call {
|
||||
foobar('Hiya')
|
||||
",
|
||||
),
|
||||
Ok(Value::String("Hiya".to_string()))
|
||||
Ok(Value::string("Hiya".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ mod function_call {
|
||||
foobar(() <str> { 'Hiya' })
|
||||
",
|
||||
),
|
||||
Ok(Value::String("Hiya".to_string()))
|
||||
Ok(Value::string("Hiya".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
@ -273,7 +273,7 @@ mod if_else {
|
||||
fn r#if() {
|
||||
assert_eq!(
|
||||
interpret("if true { 'true' }"),
|
||||
Ok(Value::String("true".to_string()))
|
||||
Ok(Value::string("true".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ mod if_else {
|
||||
}
|
||||
"
|
||||
),
|
||||
Ok(Value::String("ok".to_string()))
|
||||
Ok(Value::string("ok".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
@ -325,7 +325,7 @@ mod if_else {
|
||||
}
|
||||
"
|
||||
),
|
||||
Ok(Value::String("ok".to_string()))
|
||||
Ok(Value::string("ok".to_string()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user