@@ -43,6 +43,12 @@ use nom::error::ErrorKind;
43
43
// Our 'try readers' are a bit higher level, and are specifically supposed to be returning a valid // value::Value or some sort of failure.
44
44
//
45
45
46
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
47
+ //
48
+ // Utils
49
+ //
50
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
51
+
46
52
/// Returns the first character of a string slice.
47
53
///
48
54
/// If `input` is not empty, then its first char will be returned. Otherwise,
@@ -67,6 +73,15 @@ fn cons_str(head: char, tail: &str) -> String {
67
73
68
74
ret
69
75
}
76
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
77
+ // End Utils
78
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
79
+
80
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
81
+ //
82
+ // Predicates
83
+ //
84
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
70
85
71
86
/// Returns whether if a character can be in the tail of an identifier.
72
87
///
@@ -128,6 +143,30 @@ fn is_period_char(chr: char) -> bool {
128
143
chr == '.'
129
144
}
130
145
146
+ /// Returns whether if a given character is a whitespace.
147
+ ///
148
+ /// Clojure defines a whitespace as either a comma or an unicode whitespace.
149
+ fn is_clojure_whitespace ( c : char ) -> bool {
150
+ c. is_whitespace ( ) || c == ','
151
+ }
152
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
153
+ // End predicates
154
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
155
+
156
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
157
+ //
158
+ // Parsers
159
+ //
160
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
161
+
162
+ /// Consumes any whitespace from input, if there is any.
163
+ /// Always succeeds.
164
+ ///
165
+ /// A whitespace is either an ASCII whitespace or a comma.
166
+ fn consume_clojure_whitespaces_parser ( input : & str ) -> IResult < & str , ( ) > {
167
+ named ! ( parser<& str , & str >, take_while!( is_clojure_whitespace) ) ;
168
+ parser ( input) . map ( |( rest, _) | ( rest, ( ) ) )
169
+ }
131
170
132
171
/// Parses valid Clojure identifiers
133
172
/// Example Successes: ab, cat, -12+3, |blah|, <well>
@@ -217,6 +256,15 @@ pub fn to_value_parser<I, O: ToValue>(
217
256
) -> impl Fn ( I ) -> IResult < I , Value > {
218
257
move |input : I | parser ( input) . map ( |( rest_input, thing) | ( rest_input, thing. to_value ( ) ) )
219
258
}
259
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
260
+ // End Parsers
261
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
262
+
263
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
264
+ //
265
+ // Try-Readers
266
+ //
267
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
220
268
221
269
// @TODO make sure whitespace or 'nothing' is at the end, fail for
222
270
// float like numbers
@@ -261,7 +309,7 @@ pub fn try_read_f64(input: &str) -> IResult<&str, Value> {
261
309
/// Example Failures:
262
310
/// :12 :'a
263
311
pub fn try_read_keyword ( input : & str ) -> IResult < & str , Value > {
264
- named ! ( keyword_colon<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( ":" ) ) ) ;
312
+ named ! ( keyword_colon<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( ":" ) ) ) ;
265
313
266
314
let ( rest_input, _) = keyword_colon ( input) ?;
267
315
let ( rest_input, symbol) = symbol_parser ( rest_input) ?;
@@ -286,7 +334,7 @@ pub fn try_read_symbol(input: &str) -> IResult<&str, Value> {
286
334
/// Example Successes:
287
335
/// "this is pretty straightforward" => Value::String("this is pretty straightforward")
288
336
pub fn try_read_string ( input : & str ) -> IResult < & str , Value > {
289
- named ! ( quotation<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( "\" " ) ) ) ;
337
+ named ! ( quotation<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( "\" " ) ) ) ;
290
338
291
339
let ( rest_input, _) = quotation ( input) ?;
292
340
@@ -306,8 +354,8 @@ pub fn try_read_string(input: &str) -> IResult<&str, Value> {
306
354
/// Example Successes:
307
355
/// {:a 1} => Value::PersistentListMap {PersistentListMap { MapEntry { :a, 1} .. ]})
308
356
pub fn try_read_map ( input : & str ) -> IResult < & str , Value > {
309
- named ! ( lbracep<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( "{" ) ) ) ;
310
- named ! ( rbracep<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( "}" ) ) ) ;
357
+ named ! ( lbracep<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( "{" ) ) ) ;
358
+ named ! ( rbracep<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( "}" ) ) ) ;
311
359
let ( map_inner_input, _) = lbracep ( input) ?;
312
360
let mut map_as_vec: Vec < MapEntry > = Vec :: new ( ) ;
313
361
let mut rest_input = map_inner_input;
@@ -333,8 +381,8 @@ pub fn try_read_map(input: &str) -> IResult<&str, Value> {
333
381
/// [1 2 [5 10 15] 3]
334
382
/// => Value::PersistentVector(PersistentVector { vals: [Rc(Value::I32(1) .. Rc(Value::PersistentVector..)]})
335
383
pub fn try_read_vector ( input : & str ) -> IResult < & str , Value > {
336
- named ! ( lbracketp<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( "[" ) ) ) ;
337
- named ! ( rbracketp<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( "]" ) ) ) ;
384
+ named ! ( lbracketp<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( "[" ) ) ) ;
385
+ named ! ( rbracketp<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( "]" ) ) ) ;
338
386
let ( vector_inner_input, _) = lbracketp ( input) ?;
339
387
let mut vector_as_vec = Vec :: new ( ) ;
340
388
// What's left of our input as we read more of our PersistentVector
@@ -354,8 +402,8 @@ pub fn try_read_vector(input: &str) -> IResult<&str, Value> {
354
402
}
355
403
356
404
pub fn try_read_list ( input : & str ) -> IResult < & str , Value > {
357
- named ! ( lparenp<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( "(" ) ) ) ;
358
- named ! ( rparenp<& str , & str >, preceded!( consume_clojure_whitespaces , tag!( ")" ) ) ) ;
405
+ named ! ( lparenp<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( "(" ) ) ) ;
406
+ named ! ( rparenp<& str , & str >, preceded!( consume_clojure_whitespaces_parser , tag!( ")" ) ) ) ;
359
407
360
408
let ( list_inner_input, _) = lparenp ( input) ?;
361
409
let mut list_as_vec = Vec :: new ( ) ;
@@ -372,7 +420,7 @@ pub fn try_read_list(input: &str) -> IResult<&str, Value> {
372
420
373
421
pub fn try_read ( input : & str ) -> IResult < & str , Value > {
374
422
preceded (
375
- consume_clojure_whitespaces ,
423
+ consume_clojure_whitespaces_parser ,
376
424
alt ( (
377
425
try_read_map,
378
426
try_read_string,
@@ -386,15 +434,15 @@ pub fn try_read(input: &str) -> IResult<&str, Value> {
386
434
) ) ,
387
435
) ( input)
388
436
}
437
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
438
+ // End Try-Readers
439
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
389
440
390
- pub fn debug_try_read ( input : & str ) -> IResult < & str , Value > {
391
- let reading = try_read ( input) ;
392
- match & reading {
393
- Ok ( ( _, value) ) => println ! ( "Reading: {}" , value) ,
394
- _ => println ! ( "Reading: {:?}" , reading) ,
395
- } ;
396
- reading
397
- }
441
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
442
+ //
443
+ // Readers
444
+ //
445
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
398
446
399
447
// This is the high level read function that Clojure RS wraps
400
448
pub fn read < R : BufRead > ( reader : & mut R ) -> Value {
@@ -427,22 +475,6 @@ pub fn read<R: BufRead>(reader: &mut R) -> Value {
427
475
}
428
476
}
429
477
430
- /// Consumes any whitespace from input, if there is any.
431
- /// Always succeeds.
432
- ///
433
- /// A whitespace is either an ASCII whitespace or a comma.
434
- fn consume_clojure_whitespaces ( input : & str ) -> IResult < & str , ( ) > {
435
- named ! ( parser<& str , & str >, take_while!( is_clojure_whitespace) ) ;
436
- parser ( input) . map ( |( rest, _) | ( rest, ( ) ) )
437
- }
438
-
439
- /// Returns whether if a given character is a whitespace.
440
- ///
441
- /// Clojure defines a whitespace as either a comma or an unicode whitespace.
442
- fn is_clojure_whitespace ( c : char ) -> bool {
443
- c. is_whitespace ( ) || c == ','
444
- }
445
-
446
478
#[ cfg( test) ]
447
479
mod tests {
448
480
@@ -713,24 +745,24 @@ mod tests {
713
745
}
714
746
715
747
mod consume_clojure_whitespaces_tests {
716
- use crate :: reader:: consume_clojure_whitespaces ;
748
+ use crate :: reader:: consume_clojure_whitespaces_parser ;
717
749
#[ test]
718
750
fn consume_whitespaces_from_input ( ) {
719
751
let s = ", ,, ,1, 2, 3, 4 5,,6 " ;
720
752
assert_eq ! (
721
753
Some ( ( "1, 2, 3, 4 5,,6 " , ( ) ) ) ,
722
- consume_clojure_whitespaces ( & s) . ok( )
754
+ consume_clojure_whitespaces_parser ( & s) . ok( )
723
755
) ;
724
756
}
725
757
#[ test]
726
758
fn consume_whitespaces_from_empty_input ( ) {
727
759
let s = "" ;
728
- assert_eq ! ( None , consume_clojure_whitespaces ( & s) . ok( ) ) ;
760
+ assert_eq ! ( None , consume_clojure_whitespaces_parser ( & s) . ok( ) ) ;
729
761
}
730
762
#[ test]
731
763
fn consume_whitespaces_from_input_no_whitespace ( ) {
732
764
let s = "1, 2, 3" ;
733
- assert_eq ! ( Some ( ( "1, 2, 3" , ( ) ) ) , consume_clojure_whitespaces ( & s) . ok( ) ) ;
765
+ assert_eq ! ( Some ( ( "1, 2, 3" , ( ) ) ) , consume_clojure_whitespaces_parser ( & s) . ok( ) ) ;
734
766
}
735
767
}
736
768
0 commit comments