Skip to content

Commit cd52e24

Browse files
committed
filter lines with: Has, Excludes, Glob & Regex\!
1 parent bf65a4c commit cd52e24

File tree

7 files changed

+277
-0
lines changed

7 files changed

+277
-0
lines changed

bin/filter

2.11 MB
Binary file not shown.

filte-rs/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
target

filte-rs/Cargo.lock

+140
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

filte-rs/Cargo.toml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "filte-rs"
3+
version = "0.1.0"
4+
edition = "2021"
5+
default-run = "filter"
6+
7+
[[bin]]
8+
name = "filter"
9+
path = "src/filter.rs"
10+
11+
[dependencies]
12+
eyre = "0.6.12"
13+
glob = "0.3.1"
14+
regex = "1.10.5"
15+
thiserror = "1.0.61"

filte-rs/src/filter.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use filte_rs::*;
2+
use std::io::{stdin, BufRead};
3+
4+
fn match_all(filters: &[Filter], text: &str) -> bool {
5+
filters.iter().all(|f| f.compare(text))
6+
}
7+
8+
fn main() -> eyre::Result<()> {
9+
let filters: Vec<Filter> = std::env::args()
10+
.skip(1)
11+
.map(Filter::try_from)
12+
.collect::<Result<_, _>>()?;
13+
let stdin = stdin();
14+
for line in stdin.lock().lines() {
15+
let line = line?;
16+
if match_all(&filters, &line) {
17+
println!("{line}");
18+
}
19+
}
20+
Ok(())
21+
}

filte-rs/src/lib.rs

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#[derive(thiserror::Error, Debug)]
2+
pub enum FilterError {
3+
#[error(transparent)]
4+
RegexSyntax(#[from] regex::Error),
5+
#[error(transparent)]
6+
GlobSyntax(#[from] glob::PatternError),
7+
8+
#[error("No such filter mode {0}'")]
9+
NoFilter(char),
10+
#[error("No text in filter")]
11+
NoText,
12+
}
13+
14+
enum FilterType {
15+
Equals,
16+
Has,
17+
Excludes,
18+
Regex,
19+
Glob,
20+
}
21+
22+
#[derive(Debug)]
23+
pub enum Filter {
24+
Equals(String), // =
25+
Has(String), // +
26+
Excludes(String), // -
27+
Regex(regex::Regex), // .
28+
Glob(glob::Pattern), // ?
29+
}
30+
31+
impl TryFrom<String> for Filter {
32+
type Error = FilterError;
33+
fn try_from(text: String) -> Result<Filter, FilterError> {
34+
let mut chars = text.chars();
35+
let mode = chars.next().ok_or(FilterError::NoText)?;
36+
let mode = FilterType::try_from(mode)?;
37+
let pattern: String = chars.collect();
38+
mode.fill(pattern)
39+
}
40+
}
41+
42+
impl FilterType {
43+
fn fill(self, pattern: String) -> Result<Filter, FilterError> {
44+
Ok(match self {
45+
FilterType::Equals => Filter::Equals(pattern),
46+
FilterType::Has => Filter::Has(pattern),
47+
FilterType::Excludes => Filter::Excludes(pattern),
48+
FilterType::Regex => Filter::Regex(pattern.try_into()?),
49+
FilterType::Glob => Filter::Glob(glob::Pattern::new(&pattern)?),
50+
})
51+
}
52+
}
53+
54+
impl TryFrom<char> for FilterType {
55+
type Error = FilterError;
56+
fn try_from(v: char) -> Result<FilterType, FilterError> {
57+
Ok(match v {
58+
'=' => FilterType::Equals,
59+
'+' => FilterType::Has,
60+
'-' => FilterType::Excludes,
61+
'~' => FilterType::Regex,
62+
'?' => FilterType::Glob,
63+
x => Err(FilterError::NoFilter(x))?,
64+
})
65+
}
66+
}
67+
68+
impl Filter {
69+
pub fn compare(&self, text: &str) -> bool {
70+
use Filter::*;
71+
match self {
72+
Equals(rf) => rf == text,
73+
Has(rf) => text.contains(rf),
74+
Excludes(rf) => !text.contains(rf),
75+
Regex(rf) => rf.is_match(text),
76+
Glob(rf) => rf.matches(text),
77+
}
78+
}
79+
}
80+

filte-rs/src/map.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use filte_rs::*;
2+
use std::io::{stdin, BufRead};
3+
4+
fn match_all(filters: &[Filter], text: &str) -> bool {
5+
filters.iter().all(|f| f.compare(text))
6+
}
7+
8+
fn main() -> eyre::Result<()> {
9+
let args: Vec<Filter> = std::env::args()
10+
.skip(1)
11+
.map(Filter::try_from)
12+
.collect::<Result<_, _>>()?;
13+
println!("{args:?}");
14+
let stdin = stdin();
15+
let mut line_count = 0;
16+
for line in stdin.lock().lines() {
17+
println!("{:?}", line);
18+
}
19+
Ok(())
20+
}

0 commit comments

Comments
 (0)