@@ -63,15 +63,15 @@ fn parse_item(pair: pest::iterators::Pair<Rule>) -> JoshResult<Op> {
63
63
match pair. as_rule ( ) {
64
64
Rule :: filter => {
65
65
let v: Vec < _ > = pair. into_inner ( ) . map ( |x| unquote ( x. as_str ( ) ) ) . collect ( ) ;
66
- make_op ( v. as_slice ( ) )
66
+ make_op ( v. iter ( ) . map ( String :: as_str ) . collect :: < Vec < _ > > ( ) . as_slice ( ) )
67
67
}
68
68
Rule :: filter_nop => Ok ( Op :: Nop ) ,
69
69
Rule :: filter_subdir => Ok ( Op :: Subdir (
70
- Path :: new ( unquote ( pair. into_inner ( ) . next ( ) . unwrap ( ) . as_str ( ) ) ) . to_owned ( ) ,
70
+ Path :: new ( & unquote ( & pair. into_inner ( ) . next ( ) . unwrap ( ) . as_str ( ) ) ) . to_owned ( ) ,
71
71
) ) ,
72
72
Rule :: filter_presub => {
73
73
let mut inner = pair. into_inner ( ) ;
74
- let arg = unquote ( inner. next ( ) . unwrap ( ) . as_str ( ) ) ;
74
+ let arg = & unquote ( inner. next ( ) . unwrap ( ) . as_str ( ) ) ;
75
75
if arg. ends_with ( '/' ) {
76
76
let arg = arg. trim_end_matches ( '/' ) ;
77
77
Ok ( Op :: Chain (
@@ -91,14 +91,14 @@ fn parse_item(pair: pest::iterators::Pair<Rule>) -> JoshResult<Op> {
91
91
Rule :: filter_group => {
92
92
let v: Vec < _ > = pair. into_inner ( ) . map ( |x| unquote ( x. as_str ( ) ) ) . collect ( ) ;
93
93
94
- match v. as_slice ( ) {
94
+ match v. iter ( ) . map ( String :: as_str ) . collect :: < Vec < _ > > ( ) . as_slice ( ) {
95
95
[ args] => Ok ( Op :: Compose ( parse_group ( args) ?) ) ,
96
96
[ cmd, args] => {
97
97
let g = parse_group ( args) ?;
98
98
match * cmd {
99
99
"exclude" => Ok ( Op :: Exclude ( to_filter ( Op :: Compose ( g) ) ) ) ,
100
100
"subtract" if g. len ( ) == 2 => Ok ( Op :: Subtract ( g[ 0 ] , g[ 1 ] ) ) ,
101
- _ => Err ( josh_error ( "parse_item: no match" ) ) ,
101
+ _ => Err ( josh_error ( & format ! ( "parse_item: no match {:?}" , cmd ) ) ) ,
102
102
}
103
103
}
104
104
_ => Err ( josh_error ( "parse_item: no match {:?}" ) ) ,
@@ -199,30 +199,24 @@ fn parse_workspace(filter_spec: &str) -> JoshResult<Vec<Filter>> {
199
199
}
200
200
}
201
201
202
- // Remove double quotes from a string if present.
203
- fn unquote ( s : & str ) -> & str {
204
- if s . len ( ) < 2 {
202
+ // Parse json string if neccessary
203
+ fn unquote ( s : & str ) -> String {
204
+ if let Ok ( serde_json :: Value :: String ( s ) ) = serde_json :: from_str ( s ) {
205
205
return s;
206
206
}
207
-
208
- // We only need to check for a quote at the beginning,
209
- // because not properly quoted string will be rejected
210
- // by the grammar before we even get here
211
- if s. starts_with ( '\"' ) {
212
- return & s[ 1 ..s. len ( ) - 1 ] ;
213
- }
214
- s
207
+ return s. to_string ( ) ;
215
208
}
216
209
217
- // Add quotes to a string if if contains any chars reserved
210
+ // Encode string as json if it contains any chars reserved
218
211
// by the filter language
219
212
pub fn quote ( s : & str ) -> String {
220
213
if let Ok ( r) = Grammar :: parse ( Rule :: filter_path, s) {
221
214
if r. as_str ( ) == s {
222
215
return s. to_string ( ) ;
223
216
}
224
217
}
225
- return format ! ( "\" {}\" " , s) ;
218
+ serde_json:: to_string ( & serde_json:: Value :: String ( s. to_string ( ) ) )
219
+ . unwrap_or ( "<invalid string>" . to_string ( ) )
226
220
}
227
221
228
222
/// Create a `Filter` from a string representation
0 commit comments