@@ -2,13 +2,15 @@ use std::str::FromStr;
2
2
3
3
use winnow:: ascii:: digit1;
4
4
use winnow:: ascii:: space0;
5
+ use winnow:: combinator:: cut_err;
5
6
use winnow:: combinator:: dispatch;
6
- use winnow:: combinator:: eof;
7
7
use winnow:: combinator:: fail;
8
8
use winnow:: combinator:: opt;
9
9
use winnow:: combinator:: repeat;
10
10
use winnow:: combinator:: seq;
11
11
use winnow:: error:: ContextError ;
12
+ use winnow:: error:: StrContext ;
13
+ use winnow:: error:: StrContextValue ;
12
14
use winnow:: prelude:: * ;
13
15
use winnow:: token:: any;
14
16
use winnow:: token:: take_while;
@@ -17,7 +19,7 @@ use crate::path::Expression;
17
19
18
20
pub ( crate ) fn from_str ( mut input : & str ) -> Result < Expression , ContextError > {
19
21
let input = & mut input;
20
- path ( input) . map_err ( |e| e. into_inner ( ) . unwrap ( ) )
22
+ path. parse ( input) . map_err ( |e| e. into_inner ( ) )
21
23
}
22
24
23
25
fn path ( i : & mut & str ) -> PResult < Expression > {
@@ -31,7 +33,6 @@ fn path(i: &mut &str) -> PResult<Expression> {
31
33
} ,
32
34
)
33
35
. parse_next ( i) ?;
34
- eof. parse_next ( i) ?;
35
36
Ok ( expr)
36
37
}
37
38
@@ -41,9 +42,21 @@ fn ident(i: &mut &str) -> PResult<Expression> {
41
42
42
43
fn postfix ( i : & mut & str ) -> PResult < Child > {
43
44
dispatch ! { any;
44
- '[' => seq!( integer. map( Child :: Index ) , _: ']' ) . map( |( i, ) | i) ,
45
- '.' => raw_ident. map( Child :: Key ) ,
46
- _ => fail,
45
+ '[' => cut_err(
46
+ seq!(
47
+ integer. map( Child :: Index ) ,
48
+ _: ']' . context( StrContext :: Expected ( StrContextValue :: CharLiteral ( ']' ) ) ) ,
49
+ )
50
+ . map( |( i, ) | i)
51
+ . context( StrContext :: Label ( "subscript" ) )
52
+ ) ,
53
+ '.' => cut_err( raw_ident. map( Child :: Key ) ) ,
54
+ _ => cut_err(
55
+ fail
56
+ . context( StrContext :: Label ( "postfix" ) )
57
+ . context( StrContext :: Expected ( StrContextValue :: CharLiteral ( '[' ) ) )
58
+ . context( StrContext :: Expected ( StrContextValue :: CharLiteral ( '.' ) ) )
59
+ ) ,
47
60
}
48
61
. parse_next ( i)
49
62
}
@@ -56,6 +69,12 @@ enum Child {
56
69
fn raw_ident ( i : & mut & str ) -> PResult < String > {
57
70
take_while ( 1 .., ( 'a' ..='z' , 'A' ..='Z' , '0' ..='9' , '_' , '-' ) )
58
71
. map ( ToString :: to_string)
72
+ . context ( StrContext :: Label ( "identifier" ) )
73
+ . context ( StrContext :: Expected ( StrContextValue :: Description (
74
+ "ASCII alphanumeric" ,
75
+ ) ) )
76
+ . context ( StrContext :: Expected ( StrContextValue :: CharLiteral ( '_' ) ) )
77
+ . context ( StrContext :: Expected ( StrContextValue :: CharLiteral ( '-' ) ) )
59
78
. parse_next ( i)
60
79
}
61
80
@@ -65,6 +84,9 @@ fn integer(i: &mut &str) -> PResult<isize> {
65
84
( opt( '-' ) , digit1) . take( ) . try_map( FromStr :: from_str) ,
66
85
_: space0
67
86
)
87
+ . context ( StrContext :: Expected ( StrContextValue :: Description (
88
+ "integer" ,
89
+ ) ) )
68
90
. map ( |( i, ) | i)
69
91
. parse_next ( i)
70
92
}
@@ -121,30 +143,36 @@ mod test {
121
143
#[ test]
122
144
fn test_invalid_identifier ( ) {
123
145
let err = from_str ( "!" ) . unwrap_err ( ) ;
124
- assert_eq ! ( "" , err. to_string( ) ) ;
146
+ assert_eq ! (
147
+ "invalid identifier\n expected ASCII alphanumeric, `_`, `-`" ,
148
+ err. to_string( )
149
+ ) ;
125
150
}
126
151
127
152
#[ test]
128
153
fn test_invalid_child ( ) {
129
154
let err = from_str ( "a.." ) . unwrap_err ( ) ;
130
- assert_eq ! ( "" , err. to_string( ) ) ;
155
+ assert_eq ! (
156
+ "invalid identifier\n expected ASCII alphanumeric, `_`, `-`" ,
157
+ err. to_string( )
158
+ ) ;
131
159
}
132
160
133
161
#[ test]
134
162
fn test_invalid_subscript ( ) {
135
163
let err = from_str ( "a[b]" ) . unwrap_err ( ) ;
136
- assert_eq ! ( "" , err. to_string( ) ) ;
164
+ assert_eq ! ( "invalid subscript \n expected integer " , err. to_string( ) ) ;
137
165
}
138
166
139
167
#[ test]
140
168
fn test_incomplete_subscript ( ) {
141
169
let err = from_str ( "a[0" ) . unwrap_err ( ) ;
142
- assert_eq ! ( "" , err. to_string( ) ) ;
170
+ assert_eq ! ( "invalid subscript \n expected `]` " , err. to_string( ) ) ;
143
171
}
144
172
145
173
#[ test]
146
174
fn test_invalid_postfix ( ) {
147
175
let err = from_str ( "a!b" ) . unwrap_err ( ) ;
148
- assert_eq ! ( "" , err. to_string( ) ) ;
176
+ assert_eq ! ( "invalid postfix \n expected `[`, `.` " , err. to_string( ) ) ;
149
177
}
150
178
}
0 commit comments