Skip to content

Commit 9431bcb

Browse files
committed
experimentally holding regex with any-ref; tag 0.0.5-a1
1 parent 2dfe46c commit 9431bcb

File tree

7 files changed

+204
-13
lines changed

7 files changed

+204
-13
lines changed

.github/workflows/check.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616

1717
- uses: calcit-lang/[email protected]
1818
with:
19-
version: "0.8.50"
19+
version: "0.8.51-a1"
2020

2121
- uses: dtolnay/rust-toolchain@stable
2222
with:

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "calcit_regex"
3-
version = "0.0.4"
3+
version = "0.0.5-a1"
44
authors = ["jiyinyiyong <[email protected]>"]
55
edition = "2021"
66

@@ -13,6 +13,7 @@ crate-type = ["dylib"] # Creates dynamic lib
1313
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1414

1515
[dependencies]
16-
cirru_edn = "0.6.3"
16+
cirru_edn = "0.6.4-a1"
17+
# cirru_edn = { path = "/Users/chenyong/repo/cirru/edn.rs" }
1718
cirru_parser = "0.1.29"
1819
regex = "1.10.4"

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ regex.core/re-replace-all |1ab22c333 |\d{2} "\"X"
2525
2626
regex.core/re-split |1ab22c333 |\d{2}
2727
; [] "\"1ab" "\"c" "\"3"
28+
29+
regex.core/re-pattern |\d+
30+
; "creates any-ref to hold a native regex pattern"
2831
```
2932

3033
Install to `~/.config/calcit/modules/`, compile and provide `*.{dylib,so}` file with `./build.sh`.

calcit.cirru

Lines changed: 100 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compact.cirru

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
{} (:package |regex)
3-
:configs $ {} (:init-fn |regex.test/main!) (:reload-fn |regex.test/reload!) (:version |0.0.3)
3+
:configs $ {} (:init-fn |regex.test/main!) (:reload-fn |regex.test/reload!) (:version |0.0.5-a1)
44
:modules $ []
55
:entries $ {}
66
:files $ {}
@@ -22,6 +22,10 @@
2222
:code $ quote
2323
defn re-matches (s pattern)
2424
&call-dylib-edn (get-dylib-path "\"/dylibs/libcalcit_std") "\"re_matches" s pattern
25+
|re-pattern $ %{} :CodeEntry (:doc |)
26+
:code $ quote
27+
defn re-pattern (pattern)
28+
&call-dylib-edn (get-dylib-path "\"/dylibs/libcalcit_std") "\"re_pattern" pattern
2529
|re-replace-all $ %{} :CodeEntry (:doc |)
2630
:code $ quote
2731
defn re-replace-all (s pattern next)
@@ -52,10 +56,20 @@
5256
assert= ([] |1 |2 |34) (re-find-all |1a2a34 |\d+)
5357
assert= |1abXcX3 $ re-replace-all |1ab22c333 |\d{2} "\"X"
5458
assert= ([] "\"1ab" "\"c" "\"3") (re-split |1ab22c333 |\d{2})
59+
println "\"%%% test variable holding regex"
60+
let
61+
pattern $ re-pattern "\"\\d+"
62+
println "\"Pattern is:" pattern
63+
assert= true $ re-matches |2 pattern
64+
assert= true $ re-matches |23 pattern
65+
assert= false $ re-matches |qq pattern
66+
assert= "\"22" $ re-find |q22 pattern
67+
assert= ([] |1 |2 |3) (re-find-all |1q2q3 pattern)
68+
assert= |XabXcX $ re-replace-all |1ab22c333 pattern "\"X"
5569
:ns $ %{} :CodeEntry (:doc |)
5670
:code $ quote
5771
ns regex.test $ :require
58-
regex.core :refer $ re-matches re-find-index re-find re-find-all re-split re-replace-all
72+
regex.core :refer $ re-matches re-find-index re-find re-find-all re-split re-replace-all re-pattern
5973
regex.$meta :refer $ calcit-dirname calcit-filename
6074
|regex.util $ %{} :FileEntry
6175
:defs $ {}

src/lib.rs

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1-
use cirru_edn::{Edn, EdnListView};
1+
use std::sync::Arc;
2+
3+
use cirru_edn::{Edn, EdnAnyRef, EdnListView};
24
use regex::Regex;
35

46
#[no_mangle]
57
pub fn abi_version() -> String {
6-
String::from("0.0.7")
8+
String::from("0.0.8")
9+
}
10+
11+
#[no_mangle]
12+
pub fn re_pattern(args: Vec<Edn>) -> Result<Edn, String> {
13+
if args.len() == 1 {
14+
match &args[0] {
15+
Edn::Str(s) => match Regex::new(s) {
16+
Ok(pattern) => Ok(Edn::AnyRef(EdnAnyRef(Arc::from(pattern)))),
17+
Err(e) => Err(format!("re-pattern failed, {}", e)),
18+
},
19+
_ => Err(format!("re-pattern expect 1 string, got {:?}", args)),
20+
}
21+
} else {
22+
Err(format!("re-pattern expect 1 string, got {:?}", args))
23+
}
724
}
825

926
#[no_mangle]
@@ -14,6 +31,13 @@ pub fn re_matches(args: Vec<Edn>) -> Result<Edn, String> {
1431
Ok(p) => Ok(Edn::Bool(p.is_match(s))),
1532
Err(e) => Err(format!("re-matches failed, {}", e)),
1633
},
34+
(Edn::Str(s), Edn::AnyRef(EdnAnyRef(p))) => {
35+
if let Some(pattern) = p.downcast_ref::<Regex>() {
36+
Ok(Edn::Bool(pattern.is_match(s)))
37+
} else {
38+
Err(format!("re-matches expected a regex, got {:?}", p))
39+
}
40+
}
1741
(_, _) => Err(format!("re-matches expected 2 strings: {:?}", args)),
1842
}
1943
} else {
@@ -34,6 +58,16 @@ pub fn re_find_index(args: Vec<Edn>) -> Result<Edn, String> {
3458
Err(e) => Err(format!("re-find-index failed, {}", e)),
3559
}
3660
}
61+
(Edn::Str(s), Edn::AnyRef(EdnAnyRef(p))) => {
62+
if let Some(pattern) = p.downcast_ref::<Regex>() {
63+
match pattern.find(s) {
64+
Some(matched) => Ok(Edn::Number(matched.start() as f64)),
65+
None => Ok(Edn::Number(-1.0)), // TODO maybe nil
66+
}
67+
} else {
68+
Err(format!("re-find-index expected a regex, got {:?}", p))
69+
}
70+
}
3771
(_, _) => Err(format!("re-find-index expected 2 strings: {:?}", args)),
3872
}
3973
} else {
@@ -51,13 +85,24 @@ pub fn re_find(args: Vec<Edn>) -> Result<Edn, String> {
5185
Ok(p) => {
5286
let mut matched = p.find_iter(s);
5387
match matched.next() {
54-
Some(v) => Ok(Edn::Str(v.as_str().to_string().into())),
55-
None => Ok(Edn::Str("".to_owned().into())), // TODO maybe nil
88+
Some(v) => Ok(Edn::str(v.as_str().to_string())),
89+
None => Ok(Edn::from("")), // TODO maybe nil
5690
}
5791
}
5892
Err(e) => Err(format!("re-find failed, {}", e)),
5993
}
6094
}
95+
(Edn::Str(s), Edn::AnyRef(EdnAnyRef(p))) => {
96+
if let Some(pattern) = p.downcast_ref::<Regex>() {
97+
let mut matched = pattern.find_iter(s);
98+
match matched.next() {
99+
Some(v) => Ok(Edn::str(v.as_str().to_string())),
100+
None => Ok(Edn::from("")), // TODO maybe nil
101+
}
102+
} else {
103+
Err(format!("re-find expected a regex, got {:?}", p))
104+
}
105+
}
61106
(_, _) => Err(format!("re-find expected 2 strings: {:?}", args)),
62107
}
63108
} else {
@@ -79,6 +124,17 @@ pub fn re_find_all(args: Vec<Edn>) -> Result<Edn, String> {
79124
}
80125
Err(e) => Err(format!("re-find-all failed, {}", e)),
81126
},
127+
(Edn::Str(s), Edn::AnyRef(EdnAnyRef(p))) => {
128+
if let Some(pattern) = p.downcast_ref::<Regex>() {
129+
let mut ys: Vec<Edn> = vec![];
130+
for v in pattern.find_iter(s) {
131+
ys.push(Edn::Str(v.as_str().to_string().into()))
132+
}
133+
Ok(Edn::List(EdnListView(ys)))
134+
} else {
135+
Err(format!("re-find-all expected a regex, got {:?}", p))
136+
}
137+
}
82138
(_, _) => Err(format!("re-find-all expected 2 strings: {:?}", args)),
83139
}
84140
} else {
@@ -100,6 +156,17 @@ pub fn re_split(args: Vec<Edn>) -> Result<Edn, String> {
100156
}
101157
Err(e) => Err(format!("re-split failed, {}", e)),
102158
},
159+
(Edn::Str(s), Edn::AnyRef(EdnAnyRef(p))) => {
160+
if let Some(pattern) = p.downcast_ref::<Regex>() {
161+
let mut ys: Vec<Edn> = vec![];
162+
for piece in pattern.split(s) {
163+
ys.push(Edn::str(piece));
164+
}
165+
Ok(Edn::List(EdnListView(ys)))
166+
} else {
167+
Err(format!("re-split expected a regex, got {:?}", p))
168+
}
169+
}
103170
(_, _) => Err(format!("re-split expected 2 strings: {:?}", args)),
104171
}
105172
} else {
@@ -115,6 +182,13 @@ pub fn re_replace_all(args: Vec<Edn>) -> Result<Edn, String> {
115182
Ok(p) => Ok(Edn::str(p.replace_all(s, &**next).into_owned())),
116183
Err(e) => Err(format!("re-replace-all failed, {}", e)),
117184
},
185+
(Edn::Str(s), Edn::AnyRef(EdnAnyRef(p)), Edn::Str(next)) => {
186+
if let Some(pattern) = p.downcast_ref::<Regex>() {
187+
Ok(Edn::str(pattern.replace_all(s, &**next).into_owned()))
188+
} else {
189+
Err(format!("re-replace-all expected a regex, got {:?}", p))
190+
}
191+
}
118192
(a, b, c) => Err(format!("re-replace-all expected 3 strings: {} {} {}", a, b, c)),
119193
}
120194
} else {

0 commit comments

Comments
 (0)