Skip to content

Commit 4c0247c

Browse files
committed
Updated .gitignore
1 parent ab764e6 commit 4c0247c

File tree

4 files changed

+145
-190
lines changed

4 files changed

+145
-190
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "human_regex"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
authors = ["Chris McComb <ccmcc2012@gmail.com>"]
55
description = "A regex library for humans"
66
edition = "2021"

README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
| ⚠️ This package is under active development and doesn't do much yet. ⚠️ |
1+
| ⚠️ This package is under active development which will include breaking changes. ⚠️ |
22
| --------------------------------------------------------------------- |
33
# Regex for Humans
44
## About
@@ -9,14 +9,15 @@ to learn the complicated syntax. It is inspired by [ReadableRegex.jl](https://gi
99
### Matching a date
1010
If you want to match a date of the format `2021-10-30`, you would use the following code to generate a regex:
1111
```rust
12-
let hr = human_regex::HumanRegex::new()
13-
.begin()
14-
.exactly(4, human_regex::DIGIT)
15-
.text("-")
16-
.exactly(2, human_regex::DIGIT)
17-
.text("-")
18-
.exactly(2, human_regex::DIGIT)
19-
.end();
20-
assert!(hr.is_match("2014-01-01"));
12+
fn main() {
13+
use human_regex as hr;
14+
let regex_string = hr::begin()
15+
+ hr::exactly(4, hr::digit())
16+
+ hr::text("-")
17+
+ hr::exactly(2, hr::digit())
18+
+ hr::text("-")
19+
+ hr::exactly(2, hr::digit())
20+
+ hr::end();
21+
assert!(regex_string.to_regex().is_match("2021-10-31"))
22+
}
2123
```
22-
Specifically, this chunk of code would yield the regex `^\d{4}-\d{2}-\d{2}$`, which is exactly what we want!

src/lib.rs

Lines changed: 112 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -7,155 +7,143 @@
77
//! The goal of this crate is simple: give everybody the power of regular expressions without having
88
//! to learn the complicated syntax. It is inspired by [ReadableRegex.jl](https://github.com/jkrumbiegel/ReadableRegex.jl).
99
10-
//!# Example usage
11-
//!## Matching a date
12-
//!If you want to match a date of the format `2021-10-30`, you would use the following code to generate a regex:
13-
//!```rust
14-
//!let hr = human_regex::HumanRegex::new()
15-
//! .begin()
16-
//! .exactly(4, human_regex::DIGIT)
17-
//! .text("-")
18-
//! .exactly(2, human_regex::DIGIT)
19-
//! .text("-")
20-
//! .exactly(2, human_regex::DIGIT)
21-
//! .end();
22-
//!assert!(hr.is_match("2014-01-01"));
23-
//!```
24-
//!Specifically, this chunk of code would yield the regex `^\d{4}-\d{2}-\d{2}$`, which is exactly what we want!
10+
//! # Example usage
11+
//! ## Matching a date
12+
//! If you want to match a date of the format `2021-10-30`, you could use the following code to generate a regex:
13+
//! ```rust
14+
//! use human_regex as hr;
15+
//! let regex_string = hr::begin()
16+
//! + hr::exactly(4, hr::digit())
17+
//! + hr::text("-")
18+
//! + hr::exactly(2, hr::digit())
19+
//! + hr::text("-")
20+
//! + hr::exactly(2, hr::digit())
21+
//! + hr::end();
22+
//! assert!(regex_string.to_regex().is_match("2014-01-01"))
23+
//! ```
2524
2625
use regex::Regex;
2726
use std::fmt;
27+
use std::ops::Add;
2828

29-
/// A constant for matching any character (except for \n)
30-
pub const ANY: &str = r".";
31-
/// A constant for the digit character class (i.e., the digits 0 through 9)
32-
pub const DIGIT: &str = r"\d";
33-
/// A constant for the non-digit character class (i.e., everything BUT the digits 0-9)
34-
pub const NON_DIGIT: &str = r"\D";
35-
/// A constant for the word character class (i.e., all alphanumeric characters plus underscore)
36-
pub const WORD: &str = r"\w";
37-
/// A constant for the non-word character class (i.e., everything BUT the alphanumeric characters plus underscore)
38-
pub const NON_WORD: &str = r"\W";
29+
/// A function for matching any character (except for \n)
30+
pub fn any() -> HumanRegex {
31+
HumanRegex(r".".to_string())
32+
}
33+
/// A function for the digit character class (i.e., the digits 0 through 9)
34+
pub fn digit() -> HumanRegex {
35+
HumanRegex(r"\d".to_string())
36+
}
37+
/// A function for the non-digit character class (i.e., everything BUT the digits 0-9)
38+
pub fn non_digit() -> HumanRegex {
39+
HumanRegex(r"\D".to_string())
40+
}
41+
/// A function for the word character class (i.e., all alphanumeric characters plus underscore)
42+
pub fn word() -> HumanRegex {
43+
HumanRegex(r"\w".to_string())
44+
}
45+
/// A function for the non-word character class (i.e., everything BUT the alphanumeric characters plus underscore)
46+
pub fn non_word() -> HumanRegex {
47+
HumanRegex(r"\W".to_string())
48+
}
3949
/// A constant for the whitespace character class (i.e., space and tab)
40-
pub const WHITESPACE: &str = r"\t";
41-
/// A constant for the whitespace character class (i.e., everything BUT space and tab)
42-
pub const NON_WHITESPACE: &str = r"\T";
43-
44-
/// The HumanRegex struct which maintains and updates the regex string
45-
#[derive(Default, Debug)]
46-
pub struct HumanRegex {
47-
/// The internally-maintained true regex string
48-
pub regex_string: String,
50+
pub fn whitespace() -> HumanRegex {
51+
HumanRegex(r"\t".to_string())
52+
}
53+
/// A function for the whitespace character class (i.e., everything BUT space and tab)
54+
pub fn non_whitespace() -> HumanRegex {
55+
HumanRegex(r"\T".to_string())
4956
}
5057

51-
impl HumanRegex {
52-
/// Generate a new HumanRegex with a blank regex_string
53-
pub fn new() -> Self {
54-
HumanRegex {
55-
regex_string: String::from(""),
56-
}
57-
}
58+
/// A function to match the beginning of a string
59+
pub fn begin() -> HumanRegex {
60+
HumanRegex(r"^".to_string())
61+
}
5862

59-
/// Match exactly _n_ of a certain target
60-
pub fn exactly<T>(&self, n: u8, target: T) -> Self
61-
where
62-
T: Into<String> + fmt::Display,
63-
{
64-
let new_regex = format!("{}{}{{{}}}", self.regex_string, target, n);
65-
HumanRegex {
66-
regex_string: new_regex,
67-
}
68-
}
63+
/// A function to match the end of a string
64+
pub fn end() -> HumanRegex {
65+
HumanRegex(r"$".to_string())
66+
}
6967

70-
/// Match at least _n_ of a certain target
71-
pub fn at_least(&self, n: u8, target: &str) -> Self {
72-
let new_regex = format!("{}{}{{{},}}", self.regex_string, target, n);
73-
HumanRegex {
74-
regex_string: new_regex,
75-
}
76-
}
68+
/// The HumanRegex struct which maintains and updates the regex string
69+
#[derive(Debug)]
70+
pub struct HumanRegex(String);
7771

78-
/// Match at least _n_ and at most _m_ of a certain target
79-
pub fn at_least_at_most(&self, n: u8, m: u8, target: &str) -> Self {
80-
let new_regex = format!("{}{}{{{},{}}}", self.regex_string, target, n, m);
81-
HumanRegex {
82-
regex_string: new_regex,
83-
}
72+
impl HumanRegex {
73+
/// Convert to a rust Regex
74+
pub fn to_regex(&self) -> Regex {
75+
Regex::new(&*self.0).unwrap()
8476
}
77+
}
8578

86-
/// Match one or more of a certain target
87-
pub fn one_or_more(&self, target: &str) -> Self {
88-
let new_regex = format!("{}{}+", self.regex_string, target);
89-
HumanRegex {
90-
regex_string: new_regex,
91-
}
92-
}
79+
/// Match at least _n_ of a certain target
80+
pub fn at_least<T>(n: u8, target: T) -> HumanRegex
81+
where
82+
T: Into<String> + fmt::Display,
83+
{
84+
HumanRegex(format!("{}{{{}}}", target, n))
85+
}
9386

94-
/// Match zero or more of a certain target
95-
pub fn zero_or_more(&self, target: &str) -> Self {
96-
let new_regex = format!("{}{}*", self.regex_string, target);
97-
HumanRegex {
98-
regex_string: new_regex,
99-
}
100-
}
87+
/// Match at least _n_ and at most _m_ of a certain target
88+
pub fn at_least_at_most<T>(n: u8, m: u8, target: T) -> HumanRegex
89+
where
90+
T: Into<String> + fmt::Display,
91+
{
92+
HumanRegex(format!("{}{{{},{}}}", target, n, m))
93+
}
10194

102-
/// Match zero or one of a certain target
103-
pub fn zero_or_one(&self, target: &str) -> Self {
104-
let new_regex = format!("{}{}?", self.regex_string, target);
105-
HumanRegex {
106-
regex_string: new_regex,
107-
}
108-
}
95+
/// Match one or more of a certain target
96+
pub fn one_or_more<T>(target: T) -> HumanRegex
97+
where
98+
T: Into<String> + fmt::Display,
99+
{
100+
HumanRegex(format!("{}+", target))
101+
}
109102

110-
/// Add text directly to the match string
111-
pub fn text<T>(&self, text: T) -> Self
112-
where
113-
T: Into<String> + fmt::Display,
114-
{
115-
let new_regex = format!("{}{}", self.regex_string, text);
116-
HumanRegex {
117-
regex_string: new_regex,
118-
}
119-
}
103+
/// Match zero or more of a certain target
104+
pub fn zero_or_more<T>(target: T) -> HumanRegex
105+
where
106+
T: Into<String> + fmt::Display,
107+
{
108+
HumanRegex(format!("{}*", target))
109+
}
120110

121-
/// Represents the beginning of the text
122-
pub fn begin(&self) -> Self {
123-
let new_regex = format!("{}{}", self.regex_string, r"^");
124-
HumanRegex {
125-
regex_string: new_regex,
126-
}
127-
}
111+
/// Match zero or one of a certain target
112+
pub fn zero_or_one<T>(target: T) -> HumanRegex
113+
where
114+
T: Into<String> + fmt::Display,
115+
{
116+
HumanRegex(format!("{}?", target))
117+
}
128118

129-
/// Represents the end of the text
130-
pub fn end(&self) -> Self {
131-
let new_regex = format!("{}{}", self.regex_string, r"$");
132-
HumanRegex {
133-
regex_string: new_regex,
134-
}
135-
}
119+
/// Match exactly _n_ of a certain target
120+
pub fn exactly<T>(n: u8, target: T) -> HumanRegex
121+
where
122+
T: Into<String> + fmt::Display,
123+
{
124+
HumanRegex(format!("{}{{{}}}", target, n))
125+
}
136126

137-
/// Generates a new human regex directly from a regex string
138-
pub fn from_regex_string(regex_string: &str) -> Self {
139-
HumanRegex {
140-
regex_string: String::from(regex_string),
141-
}
142-
}
127+
/// Add generic text to the regex string
128+
pub fn text<T>(text: T) -> HumanRegex
129+
where
130+
T: Into<String> + fmt::Display,
131+
{
132+
HumanRegex(text.to_string())
133+
}
143134

144-
/// Returns the current state of the constructed regex string as a Regex object
145-
pub fn get_regex(&self) -> Regex {
146-
Regex::new(&*self.regex_string).unwrap()
147-
}
135+
impl Add for HumanRegex {
136+
type Output = Self;
148137

149-
/// Checks whether or not a string matches with the constructed regex
150-
pub fn is_match(&self, string_to_match: &str) -> bool {
151-
let re = Regex::new(&*self.regex_string).unwrap();
152-
re.is_match(string_to_match)
138+
fn add(self, rhs: Self) -> Self::Output {
139+
let owned_string = format!("{}{}", self.to_string(), rhs.to_string());
140+
HumanRegex(owned_string)
153141
}
154142
}
155143

156144
impl fmt::Display for HumanRegex {
157145
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158-
write!(f, "{}", self.regex_string)
146+
write!(f, "{}", self.0)
159147
}
160148
}
161149

tests/test.rs

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,28 @@
11
#[cfg(test)]
22
mod tests {
3-
4-
#[test]
5-
fn check_direct_regex() {
6-
let check_match = human_regex::HumanRegex::from_regex_string(r"^\d{4}-\d{2}-\d{2}$");
7-
assert!(check_match.is_match("2014-01-01"))
8-
}
9-
10-
#[test]
11-
fn check_default() {
12-
let check_match = human_regex::HumanRegex::default();
13-
assert!(check_match.is_match(""))
14-
}
15-
163
#[test]
17-
fn check_new() {
18-
let check_match = human_regex::HumanRegex::new();
19-
assert!(check_match.is_match(""))
4+
fn match_date() {
5+
use human_regex as hr;
6+
let regex_string = hr::begin()
7+
+ hr::exactly(4, hr::digit())
8+
+ hr::text("-")
9+
+ hr::exactly(2, hr::digit())
10+
+ hr::text("-")
11+
+ hr::exactly(2, hr::digit())
12+
+ hr::end();
13+
assert!(regex_string.to_regex().is_match("2014-01-01"))
2014
}
2115

2216
#[test]
23-
fn match_date() {
24-
let check_match = human_regex::HumanRegex::new()
25-
.begin()
26-
.exactly(4, human_regex::DIGIT)
27-
.text("-")
28-
.exactly(2, human_regex::DIGIT)
29-
.text("-")
30-
.exactly(2, human_regex::DIGIT)
31-
.end();
32-
assert!(check_match.is_match("2014-01-01"))
17+
#[should_panic]
18+
fn match_date_should_panic() {
19+
use human_regex as hr;
20+
let check_match = hr::begin()
21+
+ hr::exactly(4, hr::digit())
22+
+ hr::text("-")
23+
+ hr::exactly(2, hr::digit())
24+
+ hr::text("-")
25+
+ hr::exactly(2, hr::digit());
26+
assert!(check_match.to_regex().is_match("01-01-2014"))
3327
}
3428
}
35-
36-
#[test]
37-
fn test_combination() {
38-
let four_digit_regex = human_regex::HumanRegex::new().exactly(4, human_regex::DIGIT);
39-
let check_match = human_regex::HumanRegex::new()
40-
.begin()
41-
.text(four_digit_regex)
42-
.text("-")
43-
.exactly(2, human_regex::DIGIT)
44-
.text("-")
45-
.exactly(2, human_regex::DIGIT)
46-
.end();
47-
assert!(check_match.is_match("2014-01-01"))
48-
}
49-
50-
#[test]
51-
#[should_panic]
52-
fn match_date_should_panic() {
53-
let check_match = human_regex::HumanRegex::new()
54-
.begin()
55-
.exactly(4, human_regex::DIGIT)
56-
.text("-")
57-
.exactly(2, human_regex::DIGIT)
58-
.text("-")
59-
.exactly(2, human_regex::DIGIT)
60-
.end();
61-
assert!(check_match.is_match("01-01-2014"))
62-
}

0 commit comments

Comments
 (0)