Skip to content

Commit a4c04e2

Browse files
committed
boolean type and unit tests
reader refactoring according to request
1 parent b1285e0 commit a4c04e2

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

src/reader.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use crate::value::{ToValue, Value};
2323
use std::rc::Rc;
2424

2525
use std::io::BufRead;
26+
use nom::Err::Error;
27+
use nom::error::ErrorKind;
2628
//
2729
// Note; the difference between ours 'parsers'
2830
// identifier_parser
@@ -170,6 +172,7 @@ pub fn integer_parser(input: &str) -> IResult<&str, i32> {
170172
);
171173
integer_lexer(input).map(|(rest, digits)| (rest, digits.parse().unwrap()))
172174
}
175+
173176
// Currently used to create 'try_readers', which are readers (or
174177
// reader functions, at least) that are basically composable InputType
175178
// -> IResult<InputType,Value> parsers, that our normal read function
@@ -199,6 +202,18 @@ pub fn try_read_i32(input: &str) -> IResult<&str, Value> {
199202
to_value_parser(integer_parser)(input)
200203
}
201204

205+
/// Tries to parse &str into Value::Boolean
206+
/// Expects:
207+
/// Booleans
208+
/// Example success:
209+
/// true => Value::Boolean(true)
210+
/// false => Value::Boolean(false)
211+
pub fn try_read_bool(input: &str) -> IResult<&str, Value> {
212+
named!(bool_parser<&str,&str>, alt!( tag!("true") | tag!("false")));
213+
let (rest_input,bool) = bool_parser(input)?;
214+
Ok((rest_input, Value::Boolean(bool.parse().unwrap())))
215+
}
216+
202217
// Perhaps generalize this into reader macros
203218
/// Tries to parse &str into Value::Keyword
204219
/// Example Successes:
@@ -323,6 +338,7 @@ pub fn try_read(input: &str) -> IResult<&str, Value> {
323338
try_read_map,
324339
try_read_string,
325340
try_read_i32,
341+
try_read_bool,
326342
try_read_symbol,
327343
try_read_keyword,
328344
try_read_list,
@@ -498,6 +514,21 @@ mod tests {
498514
}
499515
}
500516

517+
mod try_read_bool_tests {
518+
use crate::value::Value;
519+
use crate::reader::try_read_bool;
520+
521+
#[test]
522+
fn try_read_boolean_true_test() {
523+
assert_eq!(Value::Boolean(true), try_read_bool("true ").ok().unwrap().1);
524+
}
525+
526+
#[test]
527+
fn try_read_boolean_false_test() {
528+
assert_eq!(Value::Boolean(false), try_read_bool("false ").ok().unwrap().1);
529+
}
530+
}
531+
501532
mod try_read_symbol_tests {
502533
use crate::reader::try_read_symbol;
503534
use crate::symbol::Symbol;
@@ -601,6 +632,22 @@ mod tests {
601632
try_read("[] ").ok().unwrap().1
602633
);
603634
}
635+
636+
#[test]
637+
fn try_read_bool_true_test() {
638+
assert_eq!(
639+
Value::Boolean(true),
640+
try_read("true ").ok().unwrap().1
641+
)
642+
}
643+
644+
#[test]
645+
fn try_read_bool_false_test() {
646+
assert_eq!(
647+
Value::Boolean(false),
648+
try_read("false ").ok().unwrap().1
649+
)
650+
}
604651
}
605652

606653
mod consume_clojure_whitespaces_tests {

src/type_tag.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::fmt;
33
#[derive(Debug, Clone)]
44
pub enum TypeTag {
55
I32,
6+
Boolean,
67
Symbol,
78
Keyword,
89
IFn,
@@ -17,14 +18,16 @@ pub enum TypeTag {
1718
ISeq,
1819
Nil
1920
}
21+
2022
use TypeTag::*;
2123
impl fmt::Display for TypeTag {
2224
// This trait requires `fmt` with this exact signature.
2325
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2426
let str = match self {
2527
I32 => std::string::String::from("rust.std.i32"),
28+
Boolean => std::string::String::from("rust.std.bool"),
2629
Symbol => std::string::String::from("clojure.lang.Symbol"),
27-
Keyword => std::string::String::from("clojure.lang.Keyword"),
30+
Keyword => std::string::String::from("clojure.lang.Keyword"),
2831
IFn => std::string::String::from("clojure.lang.Function"),
2932
Condition => std::string::String::from("clojure.lang.Condition"),
3033
PersistentList => std::string::String::from("clojure.lang.PersistentList"),

src/value.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use std::rc::Rc;
2828
#[derive(Debug, Clone)]
2929
pub enum Value {
3030
I32(i32),
31+
Boolean(bool),
3132
Symbol(Symbol),
3233
Keyword(Keyword),
3334
IFn(Rc<dyn IFn>),
@@ -74,6 +75,12 @@ impl PartialEq for Value {
7475
}
7576
}
7677

78+
if let Boolean(b) = self {
79+
if let Boolean(b2) = other {
80+
return b == b2;
81+
}
82+
}
83+
7784
if let Symbol(sym) = self {
7885
if let Symbol(sym2) = other {
7986
return sym == sym2;
@@ -180,6 +187,7 @@ impl Hash for Value {
180187
fn hash<H: Hasher>(&self, state: &mut H) {
181188
match self {
182189
I32(i) => i.hash(state),
190+
Boolean(b) => b.hash(state),
183191
Symbol(sym) => sym.hash(state),
184192
Keyword(kw) => kw.hash(state),
185193
IFn(_) => {
@@ -216,6 +224,7 @@ impl fmt::Display for Value {
216224
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
217225
let str = match self {
218226
I32(val) => val.to_string(),
227+
Boolean(val) => val.to_string(),
219228
Symbol(sym) => sym.to_string(),
220229
Keyword(kw) => kw.to_string(),
221230
IFn(_) => std::string::String::from("#function[]"),
@@ -254,6 +263,7 @@ impl Value {
254263
pub fn type_tag(&self) -> TypeTag {
255264
match self {
256265
Value::I32(_) => TypeTag::I32,
266+
Value::Boolean(_) => TypeTag::Boolean,
257267
Value::Symbol(_) => TypeTag::Symbol,
258268
Value::Keyword(_) => TypeTag::Keyword,
259269
Value::IFn(_) => TypeTag::IFn,
@@ -590,6 +600,11 @@ impl ToValue for i32 {
590600
Value::I32(*self)
591601
}
592602
}
603+
impl ToValue for bool {
604+
fn to_value(&self) -> Value {
605+
Value::Boolean(*self)
606+
}
607+
}
593608
impl ToValue for std::string::String {
594609
fn to_value(&self) -> Value {
595610
Value::String(self.clone())

0 commit comments

Comments
 (0)