Skip to content

Commit 43216e6

Browse files
committed
trim, triml, trimr
1 parent 2e789be commit 43216e6

File tree

10 files changed

+196
-31
lines changed

10 files changed

+196
-31
lines changed

src/clojure_string.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ pub(crate) mod join;
55
pub(crate) mod lower_case;
66
pub(crate) mod reverse;
77
pub(crate) mod starts_with_qmark_;
8+
pub(crate) mod trim;
9+
pub(crate) mod triml;
10+
pub(crate) mod trimr;
811
pub(crate) mod upper_case;

src/clojure_string/ends_with_qmark_.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55
use crate::error_message;
66
use crate::type_tag::TypeTag;
77

8-
/// clojure.string/blank? ; returns true if nil, empty or whitespace
8+
/// clojure.string/ends-with? ; returns true if string ends with substring
99
#[derive(Debug, Clone)]
1010
pub struct EndsWithFn {}
1111
impl ToValue for EndsWithFn {
@@ -41,38 +41,38 @@ mod tests {
4141

4242
#[test]
4343
fn hello_ends_with_lo() {
44-
let blank = EndsWithFn {};
44+
let ends_with = EndsWithFn {};
4545
let s = "hello";
4646
let substring = "lo";
4747
let args = vec![
4848
Rc::new(Value::String(String::from(s))),
4949
Rc::new(Value::String(String::from(substring))),
5050
];
51-
assert_eq!(Value::Boolean(true), blank.invoke(args));
51+
assert_eq!(Value::Boolean(true), ends_with.invoke(args));
5252
}
5353

5454
#[test]
5555
fn hello_does_not_end_with_klo() {
56-
let blank = EndsWithFn {};
56+
let ends_with = EndsWithFn {};
5757
let s = "hello";
5858
let substring = "klo";
5959
let args = vec![
6060
Rc::new(Value::String(String::from(s))),
6161
Rc::new(Value::String(String::from(substring))),
6262
];
63-
assert_eq!(Value::Boolean(false), blank.invoke(args));
63+
assert_eq!(Value::Boolean(false), ends_with.invoke(args));
6464
}
6565

6666
#[test]
6767
fn hello_ends_with_empty_string() {
68-
let blank = EndsWithFn {};
68+
let ends_with = EndsWithFn {};
6969
let s = "hello";
7070
let substring = "";
7171
let args = vec![
7272
Rc::new(Value::String(String::from(s))),
7373
Rc::new(Value::String(String::from(substring))),
7474
];
75-
assert_eq!(Value::Boolean(true), blank.invoke(args));
75+
assert_eq!(Value::Boolean(true), ends_with.invoke(args));
7676
}
7777
}
7878
}

src/clojure_string/includes_qmark_.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55
use crate::error_message;
66
use crate::type_tag::TypeTag;
77

8-
/// clojure.string/blank? ; returns true if nil, empty or whitespace
8+
/// clojure.string/includes? ; returns true if string contains substring
99
#[derive(Debug, Clone)]
1010
pub struct IncludesFn {}
1111
impl ToValue for IncludesFn {
@@ -41,38 +41,38 @@ mod tests {
4141

4242
#[test]
4343
fn hello_includes_ell() {
44-
let blank = IncludesFn {};
44+
let includes = IncludesFn {};
4545
let s = "hello";
4646
let substring = "ell";
4747
let args = vec![
4848
Rc::new(Value::String(String::from(s))),
4949
Rc::new(Value::String(String::from(substring))),
5050
];
51-
assert_eq!(Value::Boolean(true), blank.invoke(args));
51+
assert_eq!(Value::Boolean(true), includes.invoke(args));
5252
}
5353

5454
#[test]
5555
fn hello_does_not_include_leh() {
56-
let blank = IncludesFn {};
56+
let includes = IncludesFn {};
5757
let s = "hello";
5858
let substring = "leh";
5959
let args = vec![
6060
Rc::new(Value::String(String::from(s))),
6161
Rc::new(Value::String(String::from(substring))),
6262
];
63-
assert_eq!(Value::Boolean(false), blank.invoke(args));
63+
assert_eq!(Value::Boolean(false), includes.invoke(args));
6464
}
6565

6666
#[test]
6767
fn hello_includes_empty_string() {
68-
let blank = IncludesFn {};
68+
let includes = IncludesFn {};
6969
let s = "hello";
7070
let substring = "";
7171
let args = vec![
7272
Rc::new(Value::String(String::from(s))),
7373
Rc::new(Value::String(String::from(substring))),
7474
];
75-
assert_eq!(Value::Boolean(true), blank.invoke(args));
75+
assert_eq!(Value::Boolean(true), includes.invoke(args));
7676
}
7777
}
7878
}

src/clojure_string/lower_case.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55
use crate::error_message;
66
use crate::type_tag::TypeTag;
77

8-
/// clojure.string/upper-case ; converts characters to uppercase
8+
/// clojure.string/lower-case ; converts characters to lower case
99
#[derive(Debug, Clone)]
1010
pub struct LowerCaseFn {}
1111
impl ToValue for LowerCaseFn {
@@ -28,20 +28,20 @@ impl IFn for LowerCaseFn {
2828

2929
#[cfg(test)]
3030
mod tests {
31-
mod reverse_tests {
31+
mod lower_case_tests {
3232
use crate::clojure_string::lower_case::LowerCaseFn;
3333
use crate::ifn::IFn;
3434
use crate::value::Value;
3535
use std::rc::Rc;
3636

3737
#[test]
38-
fn reverse_string() {
39-
let reverse = LowerCaseFn {};
38+
fn lower_case_string() {
39+
let lower_case = LowerCaseFn {};
4040
let s = "1.2.3 HELLO";
4141
let args = vec![Rc::new(Value::String(String::from(s)))];
4242
assert_eq!(
4343
Value::String(String::from("1.2.3 hello")),
44-
reverse.invoke(args)
44+
lower_case.invoke(args)
4545
);
4646
}
4747
}

src/clojure_string/starts_with_qmark_.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55
use crate::error_message;
66
use crate::type_tag::TypeTag;
77

8-
/// clojure.string/blank? ; returns true if nil, empty or whitespace
8+
/// clojure.string/starts-with? ; returns true if string starts with substring
99
#[derive(Debug, Clone)]
1010
pub struct StartsWithFn {}
1111
impl ToValue for StartsWithFn {
@@ -41,38 +41,38 @@ mod tests {
4141

4242
#[test]
4343
fn hello_starts_with_hel() {
44-
let blank = StartsWithFn {};
44+
let starts_with = StartsWithFn {};
4545
let s = "hello";
4646
let substring = "hel";
4747
let args = vec![
4848
Rc::new(Value::String(String::from(s))),
4949
Rc::new(Value::String(String::from(substring))),
5050
];
51-
assert_eq!(Value::Boolean(true), blank.invoke(args));
51+
assert_eq!(Value::Boolean(true), starts_with.invoke(args));
5252
}
5353

5454
#[test]
5555
fn hello_does_not_start_with_leh() {
56-
let blank = StartsWithFn {};
56+
let starts_with = StartsWithFn {};
5757
let s = "hello";
5858
let substring = "leh";
5959
let args = vec![
6060
Rc::new(Value::String(String::from(s))),
6161
Rc::new(Value::String(String::from(substring))),
6262
];
63-
assert_eq!(Value::Boolean(false), blank.invoke(args));
63+
assert_eq!(Value::Boolean(false), starts_with.invoke(args));
6464
}
6565

6666
#[test]
6767
fn hello_starts_with_empty_string() {
68-
let blank = StartsWithFn {};
68+
let starts_with = StartsWithFn {};
6969
let s = "hello";
7070
let substring = "";
7171
let args = vec![
7272
Rc::new(Value::String(String::from(s))),
7373
Rc::new(Value::String(String::from(substring))),
7474
];
75-
assert_eq!(Value::Boolean(true), blank.invoke(args));
75+
assert_eq!(Value::Boolean(true), starts_with.invoke(args));
7676
}
7777
}
7878
}

src/clojure_string/trim.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use crate::ifn::IFn;
2+
use crate::value::{ToValue, Value};
3+
use std::rc::Rc;
4+
5+
use crate::error_message;
6+
use crate::type_tag::TypeTag;
7+
8+
/// clojure.string/trim trims white space from start and end of string
9+
#[derive(Debug, Clone)]
10+
pub struct TrimFn {}
11+
impl ToValue for TrimFn {
12+
fn to_value(&self) -> Value {
13+
Value::IFn(Rc::new(self.clone()))
14+
}
15+
}
16+
impl IFn for TrimFn {
17+
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
18+
if args.len() != 1 {
19+
return error_message::wrong_arg_count(1, args.len());
20+
} else {
21+
match args.get(0).unwrap().to_value() {
22+
Value::String(s) => Value::String(s.trim().to_string()),
23+
_a => error_message::type_mismatch(TypeTag::String, &_a.to_value()),
24+
}
25+
}
26+
}
27+
}
28+
29+
#[cfg(test)]
30+
mod tests {
31+
mod trim_tests {
32+
use crate::clojure_string::trim::TrimFn;
33+
use crate::ifn::IFn;
34+
use crate::value::Value;
35+
use std::rc::Rc;
36+
37+
#[test]
38+
fn trim() {
39+
let trim = TrimFn {};
40+
let s = " \r \t hello \n";
41+
let args = vec![Rc::new(Value::String(String::from(s)))];
42+
assert_eq!(Value::String(String::from("hello")), trim.invoke(args));
43+
}
44+
}
45+
}

src/clojure_string/triml.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::ifn::IFn;
2+
use crate::value::{ToValue, Value};
3+
use std::rc::Rc;
4+
5+
use crate::error_message;
6+
use crate::type_tag::TypeTag;
7+
8+
/// clojure.string/triml trims white space from start of string
9+
#[derive(Debug, Clone)]
10+
pub struct TrimLFn {}
11+
impl ToValue for TrimLFn {
12+
fn to_value(&self) -> Value {
13+
Value::IFn(Rc::new(self.clone()))
14+
}
15+
}
16+
impl IFn for TrimLFn {
17+
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
18+
if args.len() != 1 {
19+
return error_message::wrong_arg_count(1, args.len());
20+
} else {
21+
match args.get(0).unwrap().to_value() {
22+
Value::String(s) => Value::String(s.trim_start().to_string()),
23+
_a => error_message::type_mismatch(TypeTag::String, &_a.to_value()),
24+
}
25+
}
26+
}
27+
}
28+
29+
#[cfg(test)]
30+
mod tests {
31+
mod triml_tests {
32+
use crate::clojure_string::triml::TrimLFn;
33+
use crate::ifn::IFn;
34+
use crate::value::Value;
35+
use std::rc::Rc;
36+
37+
#[test]
38+
fn triml() {
39+
let triml = TrimLFn {};
40+
let s = " \r \t hello \n";
41+
let args = vec![Rc::new(Value::String(String::from(s)))];
42+
assert_eq!(
43+
Value::String(String::from("hello \n")),
44+
triml.invoke(args)
45+
);
46+
}
47+
}
48+
}

src/clojure_string/trimr.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::ifn::IFn;
2+
use crate::value::{ToValue, Value};
3+
use std::rc::Rc;
4+
5+
use crate::error_message;
6+
use crate::type_tag::TypeTag;
7+
8+
/// clojure.string/trimr trims white space from start of string
9+
#[derive(Debug, Clone)]
10+
pub struct TrimRFn {}
11+
impl ToValue for TrimRFn {
12+
fn to_value(&self) -> Value {
13+
Value::IFn(Rc::new(self.clone()))
14+
}
15+
}
16+
impl IFn for TrimRFn {
17+
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
18+
if args.len() != 1 {
19+
return error_message::wrong_arg_count(1, args.len());
20+
} else {
21+
match args.get(0).unwrap().to_value() {
22+
Value::String(s) => Value::String(s.trim_end().to_string()),
23+
_a => error_message::type_mismatch(TypeTag::String, &_a.to_value()),
24+
}
25+
}
26+
}
27+
}
28+
29+
#[cfg(test)]
30+
mod tests {
31+
mod trimr_tests {
32+
use crate::clojure_string::trimr::TrimRFn;
33+
use crate::ifn::IFn;
34+
use crate::value::Value;
35+
use std::rc::Rc;
36+
37+
#[test]
38+
fn trimr() {
39+
let trimr = TrimRFn {};
40+
let s = " \r \t hello \n";
41+
let args = vec![Rc::new(Value::String(String::from(s)))];
42+
assert_eq!(
43+
Value::String(String::from(" \r \t hello")),
44+
trimr.invoke(args)
45+
);
46+
}
47+
}
48+
}

src/clojure_string/upper_case.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55
use crate::error_message;
66
use crate::type_tag::TypeTag;
77

8-
/// clojure.string/upper-case ; converts characters to uppercase
8+
/// clojure.string/upper-case ; converts characters to upper case
99
#[derive(Debug, Clone)]
1010
pub struct UpperCaseFn {}
1111
impl ToValue for UpperCaseFn {
@@ -28,20 +28,20 @@ impl IFn for UpperCaseFn {
2828

2929
#[cfg(test)]
3030
mod tests {
31-
mod reverse_tests {
31+
mod upper_case_tests {
3232
use crate::clojure_string::upper_case::UpperCaseFn;
3333
use crate::ifn::IFn;
3434
use crate::value::Value;
3535
use std::rc::Rc;
3636

3737
#[test]
38-
fn reverse_string() {
39-
let reverse = UpperCaseFn {};
38+
fn upper_case_string() {
39+
let upper_case = UpperCaseFn {};
4040
let s = "1.2.3 hello";
4141
let args = vec![Rc::new(Value::String(String::from(s)))];
4242
assert_eq!(
4343
Value::String(String::from("1.2.3 HELLO")),
44-
reverse.invoke(args)
44+
upper_case.invoke(args)
4545
);
4646
}
4747
}

0 commit comments

Comments
 (0)