Add several functions for simple expressions (#407)
Co-authored-by: elkowar <5300871+elkowar@users.noreply.github.com> Co-authored-by: MartinJM <>
This commit is contained in:
parent
7648eb8086
commit
0f9847c518
4 changed files with 66 additions and 2 deletions
|
@ -27,6 +27,7 @@ All notable changes to eww will be listed here, starting at changes since versio
|
|||
- Add `scroll` widget (By: viandoxdev)
|
||||
- Add `notification` window type
|
||||
- Add drag and drop functionality to eventbox
|
||||
- Add `search`, `captures`, `stringlength`, `arraylength` and `objectlength` functions for expressions (By: MartinJM, ElKowar)
|
||||
|
||||
### Notable Internal changes
|
||||
- Rework state management completely, now making local state and dynamic widget hierarchy changes possible.
|
||||
|
|
|
@ -14,7 +14,7 @@ pub struct ConversionError {
|
|||
}
|
||||
|
||||
impl ConversionError {
|
||||
fn new(value: DynVal, target_type: &'static str, source: impl std::error::Error + 'static + Sync + Send) -> Self {
|
||||
pub fn new(value: DynVal, target_type: &'static str, source: impl std::error::Error + 'static + Sync + Send) -> Self {
|
||||
ConversionError { value, target_type, source: Some(Box::new(source)) }
|
||||
}
|
||||
}
|
||||
|
@ -214,6 +214,22 @@ impl DynVal {
|
|||
serde_json::from_str::<serde_json::Value>(&self.0)
|
||||
.map_err(|e| ConversionError::new(self.clone(), "json-value", Box::new(e)))
|
||||
}
|
||||
|
||||
pub fn as_json_array(&self) -> Result<Vec<serde_json::Value>> {
|
||||
serde_json::from_str::<serde_json::Value>(&self.0)
|
||||
.map_err(|e| ConversionError::new(self.clone(), "json-value", Box::new(e)))?
|
||||
.as_array()
|
||||
.cloned()
|
||||
.ok_or_else(|| ConversionError { value: self.clone(), target_type: "json-array", source: None })
|
||||
}
|
||||
|
||||
pub fn as_json_object(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
|
||||
serde_json::from_str::<serde_json::Value>(&self.0)
|
||||
.map_err(|e| ConversionError::new(self.clone(), "json-value", Box::new(e)))?
|
||||
.as_object()
|
||||
.cloned()
|
||||
.ok_or_else(|| ConversionError { value: self.clone(), target_type: "json-object", source: None })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -5,7 +5,10 @@ use crate::{
|
|||
dynval::{ConversionError, DynVal},
|
||||
};
|
||||
use eww_shared_util::{Span, Spanned, VarName};
|
||||
use std::{collections::HashMap, convert::TryFrom};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
convert::{TryFrom, TryInto},
|
||||
};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum EvalError {
|
||||
|
@ -276,6 +279,46 @@ fn call_expr_function(name: &str, args: Vec<DynVal>) -> Result<DynVal, EvalError
|
|||
}
|
||||
_ => Err(EvalError::WrongArgCount(name.to_string())),
|
||||
},
|
||||
"search" => match args.as_slice() {
|
||||
[string, pattern] => {
|
||||
use serde_json::Value;
|
||||
let string = string.as_string()?;
|
||||
let pattern = regex::Regex::new(&pattern.as_string()?)?;
|
||||
Ok(Value::Array(pattern.find_iter(&string).map(|x| Value::String(x.as_str().to_string())).collect())
|
||||
.try_into()?)
|
||||
}
|
||||
_ => Err(EvalError::WrongArgCount(name.to_string())),
|
||||
},
|
||||
"captures" => match args.as_slice() {
|
||||
[string, pattern] => {
|
||||
use serde_json::Value;
|
||||
let string = string.as_string()?;
|
||||
let pattern = regex::Regex::new(&pattern.as_string()?)?;
|
||||
Ok(Value::Array(
|
||||
pattern
|
||||
.captures_iter(&string)
|
||||
.map(|captures| {
|
||||
Value::Array(captures.iter().flatten().map(|x| Value::String(x.as_str().to_string())).collect())
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.try_into()?)
|
||||
}
|
||||
_ => Err(EvalError::WrongArgCount(name.to_string())),
|
||||
},
|
||||
"strlength" => match args.as_slice() {
|
||||
[string] => Ok(DynVal::from(string.as_string()?.len() as i32)),
|
||||
_ => Err(EvalError::WrongArgCount(name.to_string())),
|
||||
},
|
||||
"arraylength" => match args.as_slice() {
|
||||
[json] => Ok(DynVal::from(json.as_json_array()?.len() as i32)),
|
||||
_ => Err(EvalError::WrongArgCount(name.to_string())),
|
||||
},
|
||||
"objectlength" => match args.as_slice() {
|
||||
[json] => Ok(DynVal::from(json.as_json_object()?.len() as i32)),
|
||||
_ => Err(EvalError::WrongArgCount(name.to_string())),
|
||||
},
|
||||
|
||||
_ => Err(EvalError::UnknownFunction(name.to_string())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,8 @@ Supported currently are the following features:
|
|||
- some function calls:
|
||||
- `round(number, decimal_digits)`: Round a number to the given amount of decimals
|
||||
- `replace(string, regex, replacement)`: Replace matches of a given regex in a string
|
||||
- `search(string, regex)`: Search for a given regex in a string (returns array)
|
||||
- `captures(string, regex)`: Get the captures of a given regex in a string (returns array)
|
||||
- `hex_decode(string)`: Hex decodes the string
|
||||
- `length(value)`: Gets the length of the value, as string length, json array length, or json object length
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue