Skip to content

Commit

Permalink
fix: update filterx package version to 0.2.8 and refactor built-in fu…
Browse files Browse the repository at this point in the history
…nctions to use named expressions
  • Loading branch information
dwpeng committed Nov 12, 2024
1 parent 6955ccb commit 547f98a
Show file tree
Hide file tree
Showing 20 changed files with 157 additions and 125 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [

[workspace.package]
authors = ["dwpeng"]
version = "0.2.7"
version = "0.2.8"
edition = "2021"
description = "A simple command line tool to filter data by using python-like syntax"
license = "MIT"
Expand All @@ -18,10 +18,10 @@ homepage = "https://github.com/dwpeng/filterx"
exclude = ["spec/", "docs/"]

[workspace.dependencies]
filterx = { path = "src/filterx", version = "0.2.6" }
filterx_core = { path = "src/filterx_core", version = "0.2.6" }
filterx_engine = { path = "src/filterx_engine", version = "0.2.6" }
filterx_source = { path = "src/filterx_source", version = "0.2.7" }
filterx = { path = "src/filterx", version = "0.2.8" }
filterx_core = { path = "src/filterx_core", version = "0.2.8" }
filterx_engine = { path = "src/filterx_engine", version = "0.2.8" }
filterx_source = { path = "src/filterx_source", version = "0.2.8" }
anyhow = "1.0.89"
clap = { version = "4.5.17", features = ["derive"] }
polars = { version = "0.44.2", default-features = false, features = [
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "maturin"

[project]
name = "filterx"
version = "0.2.7"
version = "0.2.8"
description = "A simple command line tool to filter data by using python-like syntax"
readme = "README.md"
requires-python = ">=3.8"
Expand Down
41 changes: 31 additions & 10 deletions src/filterx_core/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@ pub enum Value {
Ident((String, Box<Value>)),
AttrMethod(AttrMethod),
File(File),
Expr(Expr),
NamedExpr(NamedExpr),
// Slice(Slice),
Null,
Na,
None,
}

impl Value {
pub fn named_expr(name: Option<String>, expr: Expr) -> Self {
Value::NamedExpr(NamedExpr { name, expr })
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct NamedExpr {
pub name: Option<String>,
pub expr: Expr,
}

impl Literal for Value {
fn lit(self) -> Expr {
match self {
Expand Down Expand Up @@ -120,7 +132,7 @@ impl Value {
Value::Str(s) => s.clone().lit(),
Value::Item(c) => col(c.col_name.clone()),
Value::Name(n) => col(n.name.clone()),
Value::Expr(e) => e.clone(),
Value::NamedExpr(e) => e.expr.clone(),
Value::Null => Expr::Literal(LiteralValue::Null),
Value::Na => Expr::Literal(LiteralValue::Null),
Value::None => return Err(FilterxError::RuntimeError("function return None".into())),
Expand All @@ -143,12 +155,14 @@ impl Value {
}

pub fn string(&self) -> FilterxResult<String> {
let s = match self {
Value::Str(s) => s.clone(),
Value::Expr(Expr::Literal(LiteralValue::String(s))) => s.to_string(),
_ => panic!("not a string"),
};
Ok(s)
match self {
Value::Str(s) => Ok(s.to_owned()),
_ => {
return Err(FilterxError::RuntimeError(
"Only Str can convert to string".into(),
))
}
}
}

pub fn u32(&self) -> FilterxResult<u32> {
Expand All @@ -165,6 +179,10 @@ impl Value {
Value::Item(c) => Ok(c.col_name.as_str()),
Value::Name(n) => Ok(n.name.as_str()),
Value::Str(s) => Ok(s.as_str()),
Value::NamedExpr(e) => match e.name {
Some(ref name) => Ok(name.as_str()),
None => return Err(FilterxError::RuntimeError("Can't find column name.".into())),
},
_ => {
let mut h = Hint::new();
h.white("Expected the following types as a column name: ")
Expand Down Expand Up @@ -200,7 +218,7 @@ impl Value {

pub fn is_expr(&self) -> bool {
match self {
Value::Expr(_) => true,
Value::NamedExpr(_) => true,
_ => false,
}
}
Expand Down Expand Up @@ -321,7 +339,10 @@ impl Value {
Value::Float(f) => f.to_string(),
Value::Bool(b) => b.to_string(),
Value::Str(s) => format!("'{}'", s),
Value::Expr(e) => e.to_string(),
Value::NamedExpr(e) => {
let s = format!("NamedExpr(name={:?}, expr={:?})", e.name, e.expr);
s
}
Value::List(l) => {
let mut s = String::from("[");
for (i, v) in l.iter().enumerate() {
Expand Down
8 changes: 6 additions & 2 deletions src/filterx_engine/src/eval_vm/call/builtin/abs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ pub fn abs<'a>(
inplace: bool,
) -> FilterxResult<value::Value> {
expect_args_len(args, 1)?;
let col_name = eval_col!(vm, &args[0], "abs: expected a column name as first argument");
let col_name = eval_col!(
vm,
&args[0],
"abs: expected a column name as first argument"
);
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let e = col(col_name).abs();
if inplace {
vm.source.with_column(e.alias(col_name), None);
return Ok(value::Value::None);
}
Ok(value::Value::Expr(e))
Ok(value::Value::named_expr(None, e))
}
13 changes: 7 additions & 6 deletions src/filterx_engine/src/eval_vm/call/builtin/cast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use polars::prelude::{col, DataType};
use polars::prelude::DataType;

pub fn cast<'a>(
vm: &'a mut Vm,
Expand All @@ -13,8 +13,9 @@ pub fn cast<'a>(
&args[0],
"cast: expected a column name as first argument",
);
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let name = col_name.column()?;
let e = col_name.expr()?;
vm.source.has_column(name);
let new_type = match new_type.to_lowercase().as_str() {
"int" => DataType::Int32,
"float" => DataType::Float32,
Expand All @@ -39,11 +40,11 @@ pub fn cast<'a>(
}
};

let e = col(col_name).cast(new_type);
let e = e.cast(new_type);
if inplace {
vm.source.with_column(e.alias(col_name), None);
vm.source.with_column(e.alias(name), None);
return Ok(value::Value::None);
}

Ok(value::Value::Expr(e))
Ok(value::Value::named_expr(Some(name.to_string()), e))
}
10 changes: 5 additions & 5 deletions src/filterx_engine/src/eval_vm/call/builtin/drop_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ pub fn drop_null<'a>(
&args[0],
"len: expected a column name as first argument"
);
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let e = col(col_name).drop_nulls();
let name = col_name.column()?;
vm.source.has_column(name);
let e = col(name).drop_nulls();
if inplace {
vm.source.with_column(e.alias(col_name), None);
vm.source.with_column(e.alias(name), None);
return Ok(value::Value::None);
}
Ok(value::Value::Expr(e))
Ok(value::Value::named_expr(None, e))
}
13 changes: 7 additions & 6 deletions src/filterx_engine/src/eval_vm/call/builtin/fill.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use polars::prelude::{col, Literal};
use polars::prelude::Literal;
use value::Value;

pub fn fill<'a>(
Expand All @@ -20,13 +20,14 @@ pub fn fill<'a>(
"fill: expected a constant value as second argument",
Constant
);
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let e = col(col_name).fill_null(const_value.lit());
let name = col_name.column()?;
let e = col_name.expr()?;
vm.source.has_column(name);
let e = e.fill_null(const_value.lit());
if inplace {
let lazy = &mut vm.source;
lazy.with_column(e.alias(col_name), None);
lazy.with_column(e.alias(name), None);
return Ok(Value::None);
}
Ok(Value::Expr(e))
Ok(Value::named_expr(Some(name.to_string()), e))
}
2 changes: 1 addition & 1 deletion src/filterx_engine/src/eval_vm/call/builtin/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ pub fn gc<'a>(vm: &'a mut Vm, args: &Vec<ast::Expr>) -> FilterxResult<value::Val
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let e = col(col_name).map(compute_gc, GetOutput::float_type());
return Ok(value::Value::Expr(e));
return Ok(value::Value::named_expr(None, e));
}
18 changes: 11 additions & 7 deletions src/filterx_engine/src/eval_vm/call/builtin/len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ use super::*;

pub fn len<'a>(vm: &'a mut Vm, args: &Vec<ast::Expr>) -> FilterxResult<value::Value> {
expect_args_len(args, 1)?;
let col_name = eval_col!(vm, &args[0], "len: expected a column name as first argument");
vm.source.has_column(col_name.column()?);
let col_name = col_name.expr()?.str();
let e;
let col_name = eval_col!(
vm,
&args[0],
"len: expected a column name as first argument"
);
let name = col_name.column()?;
let mut e = col_name.expr()?;
vm.source.has_column(name);
// !Note: Only csv has a character length.
if vm.source_type == "csv".into() {
e = col_name.len_chars();
e = e.str().len_chars();
} else {
e = col_name.len_bytes();
e = e.str().len_bytes();
}
Ok(value::Value::Expr(e))
Ok(value::Value::named_expr(None, e))
}
16 changes: 11 additions & 5 deletions src/filterx_engine/src/eval_vm/call/builtin/lower.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use polars::prelude::col;
use value::NamedExpr;

use super::*;

Expand All @@ -13,13 +13,19 @@ pub fn lower<'a>(
&args[0],
"lower: expected a column name as first argument"
);
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let name = col_name.column()?;
let e = col_name.expr()?;
vm.source.has_column(name);
if inplace {
vm.source
.with_column(col(col_name).str().to_lowercase().alias(col_name), None);
.with_column(e.str().to_lowercase().alias(name), None);
return Ok(value::Value::None);
}

Ok(value::Value::Expr(col(col_name).str().to_lowercase()))
let ne = NamedExpr {
name: Some(name.to_string()),
expr: e.str().to_lowercase().alias(name),
};

Ok(value::Value::NamedExpr(ne))
}
5 changes: 4 additions & 1 deletion src/filterx_engine/src/eval_vm/call/builtin/nr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ use polars::prelude::Literal;

pub fn nr<'a>(_vm: &'a mut Vm, args: &Vec<ast::Expr>) -> FilterxResult<value::Value> {
expect_args_len(args, 0)?;
Ok(value::Value::Expr(1.lit().alias("nr").cum_sum(false)))
Ok(value::Value::named_expr(
Some("NR".to_owned()),
1.lit().alias("nr").cum_sum(false),
))
}
34 changes: 13 additions & 21 deletions src/filterx_engine/src/eval_vm/call/builtin/replace.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use polars::prelude::{col, lit};
use polars::prelude::lit;

use super::*;

Expand All @@ -15,8 +15,9 @@ pub fn replace<'a>(
&args[0],
"replace: expected a column name as first argument"
);
let col_name = col_name.column()?;
vm.source.has_column(col_name);
let name = col_name.column()?;
let e = col_name.expr()?;
vm.source.has_column(name);

let patt = eval!(
vm,
Expand All @@ -39,28 +40,19 @@ pub fn replace<'a>(
if inplace {
vm.source.with_column(
match many {
true => col(col_name)
.str()
.replace_all(patt, repl, true)
.alias(col_name),
false => col(col_name)
.str()
.replace(patt, repl, true)
.alias(col_name),
true => e.str().replace_all(patt, repl, true).alias(name),
false => e.str().replace(patt, repl, true).alias(name),
},
None,
);
return Ok(value::Value::None);
}

Ok(value::Value::Expr(match many {
true => col(col_name)
.str()
.replace_all(patt, repl, true)
.alias(col_name),
false => col(col_name)
.str()
.replace(patt, repl, true)
.alias(col_name),
}))
Ok(value::Value::named_expr(
Some(name.to_string()),
match many {
true => e.str().replace_all(patt, repl, true).alias(name),
false => e.str().replace(patt, repl, true).alias(name),
},
))
}
Loading

0 comments on commit 547f98a

Please sign in to comment.