Skip to content

Commit d9d5695

Browse files
erkkikeranenTko1
authored andcommitted
regex type
1 parent 6fc04e0 commit d9d5695

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ nom = "5.1"
1212
rand = "0.7"
1313
itertools= "0.9"
1414
url = "2.1.1"
15+
regex = "1.3.7"
1516
reqwest = { version = "0.10.4", features = ["blocking"] }

src/reader.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ pub fn try_read_symbol(input: &str) -> IResult<&str, Value> {
364364
/// Example Successes:
365365
/// nil => Value::Nil
366366
pub fn try_read_nil(input: &str) -> IResult<&str, Value> {
367-
let (rest_input, _) = verify(identifier_parser,|ident: &str| ident == "nil")(input)?;
368-
Ok((rest_input,Value::Nil))
367+
let (rest_input, _) = verify(identifier_parser, |ident: &str| ident == "nil")(input)?;
368+
Ok((rest_input, Value::Nil))
369369
}
370370

371371
// @TODO allow escaped strings
@@ -388,6 +388,23 @@ pub fn try_read_string(input: &str) -> IResult<&str, Value> {
388388
to_value_parser(string_parser)(rest_input)
389389
}
390390

391+
/// Tries to parse &str into Value::Pattern
392+
/// Example Successes:
393+
/// #"this is pretty straightforward" => Value::Pattern("this is pretty straightforward")
394+
pub fn try_read_pattern(input: &str) -> IResult<&str, Value> {
395+
named!(hash_quotation<&str, &str>, preceded!(consume_clojure_whitespaces_parser, tag!("#\"")));
396+
397+
let (rest_input, _) = hash_quotation(input)?;
398+
named!(
399+
pattern_parser<&str, regex::Regex>,
400+
map!(
401+
terminated!(take_until!("\""), tag("\"")),
402+
|v| regex::Regex::new(v).unwrap()
403+
)
404+
);
405+
to_value_parser(pattern_parser)(rest_input)
406+
}
407+
391408
// @TODO Perhaps generalize this, or even generalize it as a reader macro
392409
/// Tries to parse &str into Value::PersistentListMap, or some other Value::..Map
393410
/// Example Successes:
@@ -492,6 +509,7 @@ pub fn try_read(input: &str) -> IResult<&str, Value> {
492509
try_read_keyword,
493510
try_read_list,
494511
try_read_vector,
512+
try_read_pattern,
495513
)),
496514
)(input)
497515
}
@@ -726,8 +744,8 @@ mod tests {
726744
use crate::persistent_vector;
727745
use crate::reader::try_read;
728746
use crate::symbol::Symbol;
729-
use crate::value::Value;
730747
use crate::value::Value::{PersistentList, PersistentListMap, PersistentVector};
748+
use crate::value::{ToValue, Value};
731749

732750
#[test]
733751
fn try_read_empty_map_test() {
@@ -809,6 +827,14 @@ mod tests {
809827
fn try_read_bool_false_test() {
810828
assert_eq!(Value::Boolean(false), try_read("false ").ok().unwrap().1)
811829
}
830+
831+
#[test]
832+
fn try_read_regex_pattern_test() {
833+
assert_eq!(
834+
Value::Pattern(regex::Regex::new("hello").unwrap()),
835+
try_read("#\"hello\" ").ok().unwrap().1
836+
);
837+
}
812838
}
813839

814840
mod consume_clojure_whitespaces_tests {

src/type_tag.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub enum TypeTag {
1818
Integer,
1919
ISeq,
2020
Nil,
21+
Pattern,
2122
}
2223

2324
use TypeTag::*;
@@ -40,6 +41,7 @@ impl fmt::Display for TypeTag {
4041
TypeTag::Integer => std::string::String::from("clojure.lang.Integer"),
4142
ISeq => std::string::String::from("clojure.lang.ISeq"),
4243
Nil => std::string::String::from("clojure.lang.Nil"),
44+
Pattern => std::string::String::from("rust.regex"),
4345
};
4446
write!(f, "{}", str)
4547
}

src/value.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub enum Value {
6161

6262
String(std::string::String),
6363
Nil,
64+
Pattern(regex::Regex),
6465
}
6566
use crate::value::Value::*;
6667

@@ -90,6 +91,7 @@ impl PartialEq for Value {
9091
(LetMacro, LetMacro) => true,
9192
(String(string), String(string2)) => string == string2,
9293
(Nil, Nil) => true,
94+
(Pattern(p1), Pattern(p2)) => p1.as_str() == p2.as_str(),
9395
_ => false,
9496
}
9597
}
@@ -142,6 +144,7 @@ impl Hash for Value {
142144
IfMacro => ValueHash::IfMacro.hash(state),
143145

144146
String(string) => string.hash(state),
147+
Pattern(p) => p.as_str().hash(state),
145148
Nil => ValueHash::Nil.hash(state),
146149
}
147150
// self.id.hash(state);
@@ -170,6 +173,9 @@ impl fmt::Display for Value {
170173
IfMacro => std::string::String::from("#macro[if*]"),
171174
LetMacro => std::string::String::from("#macro[let*]"),
172175
Value::String(string) => string.clone(),
176+
Pattern(pattern) => {
177+
std::string::String::from("#\"".to_owned() + pattern.as_str().clone() + "\"")
178+
}
173179
Nil => std::string::String::from("nil"),
174180
};
175181
write!(f, "{}", str)
@@ -214,6 +220,7 @@ impl Value {
214220
Value::IfMacro => TypeTag::Macro,
215221
Value::String(_) => TypeTag::String,
216222
Value::Nil => TypeTag::Nil,
223+
Value::Pattern(_) => TypeTag::Pattern,
217224
}
218225
}
219226

@@ -582,6 +589,11 @@ impl ToValue for str {
582589
Value::String(std::string::String::from(self))
583590
}
584591
}
592+
impl ToValue for regex::Regex {
593+
fn to_value(&self) -> Value {
594+
Value::Pattern(self.clone())
595+
}
596+
}
585597
impl ToValue for Symbol {
586598
fn to_value(&self) -> Value {
587599
Value::Symbol(self.clone())

0 commit comments

Comments
 (0)