Skip to content

Commit 5330843

Browse files
committed
regex type
1 parent c272638 commit 5330843

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
@@ -60,6 +60,7 @@ pub enum Value {
6060

6161
String(std::string::String),
6262
Nil,
63+
Pattern(regex::Regex),
6364
}
6465
use crate::value::Value::*;
6566

@@ -89,6 +90,7 @@ impl PartialEq for Value {
8990
(LetMacro, LetMacro) => true,
9091
(String(string), String(string2)) => string == string2,
9192
(Nil, Nil) => true,
93+
(Pattern(p1), Pattern(p2)) => p1.as_str() == p2.as_str(),
9294
_ => false,
9395
}
9496
}
@@ -141,6 +143,7 @@ impl Hash for Value {
141143
IfMacro => ValueHash::IfMacro.hash(state),
142144

143145
String(string) => string.hash(state),
146+
Pattern(p) => p.as_str().hash(state),
144147
Nil => ValueHash::Nil.hash(state),
145148
}
146149
// self.id.hash(state);
@@ -169,6 +172,9 @@ impl fmt::Display for Value {
169172
IfMacro => std::string::String::from("#macro[if*]"),
170173
LetMacro => std::string::String::from("#macro[let*]"),
171174
Value::String(string) => string.clone(),
175+
Pattern(pattern) => {
176+
std::string::String::from("#\"".to_owned() + pattern.as_str().clone() + "\"")
177+
}
172178
Nil => std::string::String::from("nil"),
173179
};
174180
write!(f, "{}", str)
@@ -213,6 +219,7 @@ impl Value {
213219
Value::IfMacro => TypeTag::Macro,
214220
Value::String(_) => TypeTag::String,
215221
Value::Nil => TypeTag::Nil,
222+
Value::Pattern(_) => TypeTag::Pattern,
216223
}
217224
}
218225

@@ -581,6 +588,11 @@ impl ToValue for str {
581588
Value::String(std::string::String::from(self))
582589
}
583590
}
591+
impl ToValue for regex::Regex {
592+
fn to_value(&self) -> Value {
593+
Value::Pattern(self.clone())
594+
}
595+
}
584596
impl ToValue for Symbol {
585597
fn to_value(&self) -> Value {
586598
Value::Symbol(self.clone())

0 commit comments

Comments
 (0)