1
1
use nom:: anychar;
2
2
3
+ #[ cfg( feature="wtf8" ) ]
4
+ use wtf8;
5
+
3
6
use helpers:: StrSpan ;
4
7
use ast:: * ;
5
8
6
- named ! ( escapedchar<StrSpan , Option <char >>,
9
+ #[ cfg( feature="wtf8" ) ]
10
+ fn cp_from_char ( c : char ) -> wtf8:: CodePoint {
11
+ wtf8:: CodePoint :: from_char ( c)
12
+ }
13
+ #[ cfg( feature="wtf8" ) ]
14
+ fn cp_from_u32 ( n : u32 ) -> Option < wtf8:: CodePoint > {
15
+ wtf8:: CodePoint :: from_u32 ( n)
16
+ }
17
+ #[ cfg( not( feature="wtf8" ) ) ]
18
+ fn cp_from_char ( c : char ) -> char {
19
+ c
20
+ }
21
+ #[ cfg( not( feature="wtf8" ) ) ]
22
+ fn cp_from_u32 ( n : u32 ) -> Option < char > {
23
+ :: std:: char:: from_u32 ( n)
24
+ }
25
+
26
+ named ! ( escapedchar<StrSpan , Option <PyStringCodePoint >>,
7
27
preceded!( char !( '\\' ) ,
8
28
alt!(
9
29
char !( '\n' ) => { |_| None }
10
- | char !( '\\' ) => { |_| Some ( '\\' ) }
11
- | char !( '\'' ) => { |_| Some ( '\'' ) }
12
- | char !( '"' ) => { |_| Some ( '"' ) }
13
- | char !( 'a' ) => { |_| Some ( '\x07' ) } // BEL
14
- | char !( 'b' ) => { |_| Some ( '\x08' ) } // BS
15
- | char !( 'f' ) => { |_| Some ( '\x0c' ) } // FF
16
- | char !( 'n' ) => { |_| Some ( '\n' ) }
17
- | char !( 'r' ) => { |_| Some ( '\r' ) }
18
- | char !( 't' ) => { |_| Some ( '\t' ) }
19
- | char !( 'v' ) => { |_| Some ( '\x0b' ) } // VT
30
+ | char !( '\\' ) => { |_| Some ( cp_from_char ( '\\' ) ) }
31
+ | char !( '\'' ) => { |_| Some ( cp_from_char ( '\'' ) ) }
32
+ | char !( '"' ) => { |_| Some ( cp_from_char ( '"' ) ) }
33
+ | char !( 'a' ) => { |_| Some ( cp_from_char ( '\x07' ) ) } // BEL
34
+ | char !( 'b' ) => { |_| Some ( cp_from_char ( '\x08' ) ) } // BS
35
+ | char !( 'f' ) => { |_| Some ( cp_from_char ( '\x0c' ) ) } // FF
36
+ | char !( 'n' ) => { |_| Some ( cp_from_char ( '\n' ) ) }
37
+ | char !( 'r' ) => { |_| Some ( cp_from_char ( '\r' ) ) }
38
+ | char !( 't' ) => { |_| Some ( cp_from_char ( '\t' ) ) }
39
+ | char !( 'v' ) => { |_| Some ( cp_from_char ( '\x0b' ) ) } // VT
20
40
| tuple!( one_of!( "01234567" ) , opt!( one_of!( "01234567" ) ) , opt!( one_of!( "01234567" ) ) ) => { |( c1, c2, c3) : ( char , Option <char >, Option <char >) |
21
41
match ( c1. to_digit( 8 ) , c2. and_then( |c| c. to_digit( 8 ) ) , c3. and_then( |c| c. to_digit( 8 ) ) ) {
22
- ( Some ( d1) , Some ( d2) , Some ( d3) ) => :: std :: char :: from_u32 ( ( d1 << 6 ) + ( d2 << 3 ) + d3) ,
23
- ( Some ( d1) , Some ( d2) , None ) => :: std :: char :: from_u32 ( ( d1 << 3 ) + d2) ,
24
- ( Some ( d1) , None , None ) => :: std :: char :: from_u32 ( d1) ,
42
+ ( Some ( d1) , Some ( d2) , Some ( d3) ) => cp_from_u32 ( ( d1 << 6 ) + ( d2 << 3 ) + d3) ,
43
+ ( Some ( d1) , Some ( d2) , None ) => cp_from_u32 ( ( d1 << 3 ) + d2) ,
44
+ ( Some ( d1) , None , None ) => cp_from_u32 ( d1) ,
25
45
_ => unreachable!( ) ,
26
46
}
27
47
}
28
48
| preceded!( char !( 'x' ) , tuple!( one_of!( "0123456789abcdefABCDEF" ) , one_of!( "0123456789abcdefABCDEF" ) ) ) => { |( c1, c2) : ( char , char ) |
29
49
match ( c1. to_digit( 16 ) , c2. to_digit( 16 ) ) {
30
- ( Some ( d1) , Some ( d2) ) => :: std :: char :: from_u32 ( ( d1 << 4 ) + d2) ,
50
+ ( Some ( d1) , Some ( d2) ) => cp_from_u32 ( ( d1 << 4 ) + d2) ,
31
51
_ => unreachable!( ) ,
32
52
}
33
53
}
@@ -38,14 +58,14 @@ named!(escapedchar<StrSpan, Option<char>>,
38
58
| preceded!( char !( 'u' ) , count!( one_of!( "0123456789abcdefABCDEF" ) , 4 ) ) => { |v: Vec <char >| {
39
59
let it: Vec <u32 > = v. iter( ) . map( |c| c. to_digit( 16 ) . unwrap( ) ) . collect( ) ;
40
60
if let [ d1, d2, d3, d4] = & it[ ..] {
41
- :: std :: char :: from_u32 ( ( d1 << 12 ) + ( d2 << 8 ) + ( d3 << 4 ) + d4)
61
+ cp_from_u32 ( ( d1 << 12 ) + ( d2 << 8 ) + ( d3 << 4 ) + d4)
42
62
}
43
63
else { unreachable!( ) }
44
64
} }
45
65
| preceded!( char !( 'U' ) , count!( one_of!( "0123456789abcdefABCDEF" ) , 8 ) ) => { |v: Vec <char >| {
46
66
let it: Vec <u32 > = v. iter( ) . map( |c| c. to_digit( 16 ) . unwrap( ) ) . collect( ) ;
47
67
if let [ d1, d2, d3, d4, d5, d6, d7, d8] = & it[ ..] {
48
- :: std :: char :: from_u32 ( ( d1 << 28 ) + ( d2 << 24 ) + ( d3 << 20 ) + ( d4 << 16 ) +
68
+ cp_from_u32 ( ( d1 << 28 ) + ( d2 << 24 ) + ( d3 << 20 ) + ( d4 << 16 ) +
49
69
( d5 << 12 ) + ( d6 << 8 ) + ( d7 << 4 ) + d8)
50
70
}
51
71
else { unreachable!( ) }
@@ -54,51 +74,51 @@ named!(escapedchar<StrSpan, Option<char>>,
54
74
)
55
75
) ;
56
76
57
- named_args ! ( shortstring( quote: char ) <StrSpan , String >,
77
+ named_args ! ( shortstring( quote: char ) <StrSpan , PyStringContent >,
58
78
fold_many0!(
59
79
alt!(
60
80
call!( escapedchar)
61
- | verify!( anychar, |c: char | c != quote) => { |c: char | Some ( c ) }
81
+ | verify!( anychar, |c: char | c != quote) => { |c: char | Some ( cp_from_char ( c ) ) }
62
82
) ,
63
- String :: new( ) ,
64
- |mut acc: String , c: Option <char >| { match c { Some ( c) => acc. push_str ( & c . to_string ( ) ) , None => ( ) } ; acc }
83
+ PyStringContent :: new( ) ,
84
+ |mut acc: PyStringContent , c: Option <PyStringCodePoint >| { match c { Some ( c) => acc. push ( c ) , None => ( ) } ; acc }
65
85
)
66
86
) ;
67
87
68
- named_args ! ( longstring( quote: char ) <StrSpan , String >,
88
+ named_args ! ( longstring( quote: char ) <StrSpan , PyStringContent >,
69
89
fold_many0!(
70
90
alt!(
71
91
call!( escapedchar)
72
- | verify!( tuple!( peek!( take!( 3 ) ) , anychar) , |( s, _) : ( StrSpan , _) | { s. fragment. 0 . chars( ) . collect:: <Vec <char >>( ) != vec![ quote, quote, quote] } ) => { |( _, c) | Some ( c ) }
92
+ | verify!( tuple!( peek!( take!( 3 ) ) , anychar) , |( s, _) : ( StrSpan , _) | { s. fragment. 0 . chars( ) . collect:: <Vec <char >>( ) != vec![ quote, quote, quote] } ) => { |( _, c) | Some ( cp_from_char ( c ) ) }
73
93
) ,
74
- String :: new( ) ,
75
- |mut acc: String , c: Option <char >| { match c { Some ( c) => acc. push_str ( & c . to_string ( ) ) , None => ( ) } ; acc }
94
+ PyStringContent :: new( ) ,
95
+ |mut acc: PyStringContent , c: Option <PyStringCodePoint >| { match c { Some ( c) => acc. push ( c ) , None => ( ) } ; acc }
76
96
)
77
97
) ;
78
98
79
- named_args ! ( shortrawstring( quote: char ) <StrSpan , String >,
99
+ named_args ! ( shortrawstring( quote: char ) <StrSpan , PyStringContent >,
80
100
fold_many0!(
81
101
alt!(
82
- tuple!( char !( '\\' ) , anychar) => { |( c1, c2) | ( c1 , Some ( c2 ) ) }
83
- | verify!( none_of!( "\\ " ) , |c: char | c != quote) => { |c: char | ( c , None ) }
102
+ tuple!( char !( '\\' ) , anychar) => { |( c1, c2) | ( cp_from_char ( c1 ) , Some ( cp_from_char ( c2 ) ) ) }
103
+ | verify!( none_of!( "\\ " ) , |c: char | c != quote) => { |c: char | ( cp_from_char ( c ) , None ) }
84
104
) ,
85
- String :: new( ) ,
86
- |mut acc: String , ( c1, c2) : ( char , Option <char >) | {
105
+ PyStringContent :: new( ) ,
106
+ |mut acc: PyStringContent , ( c1, c2) : ( PyStringCodePoint , Option <PyStringCodePoint >) | {
87
107
acc. push( c1) ;
88
108
match c2 { Some ( c) => acc. push( c) , None => ( ) } ;
89
109
acc
90
110
}
91
111
)
92
112
) ;
93
113
94
- named_args ! ( longrawstring( quote: char ) <StrSpan , String >,
114
+ named_args ! ( longrawstring( quote: char ) <StrSpan , PyStringContent >,
95
115
fold_many0!(
96
116
alt!(
97
- tuple!( char !( '\\' ) , anychar) => { |( c1, c2) | ( c1 , Some ( c2 ) ) }
98
- | verify!( tuple!( peek!( take!( 3 ) ) , none_of!( "\\ " ) ) , |( s, _) : ( StrSpan , _) | { s. fragment. 0 . chars( ) . collect:: <Vec <char >>( ) != vec![ quote, quote, quote] } ) => { |( _, c) | ( c , None ) }
117
+ tuple!( char !( '\\' ) , anychar) => { |( c1, c2) | ( cp_from_char ( c1 ) , Some ( cp_from_char ( c2 ) ) ) }
118
+ | verify!( tuple!( peek!( take!( 3 ) ) , none_of!( "\\ " ) ) , |( s, _) : ( StrSpan , _) | { s. fragment. 0 . chars( ) . collect:: <Vec <char >>( ) != vec![ quote, quote, quote] } ) => { |( _, c) | ( cp_from_char ( c ) , None ) }
99
119
) ,
100
- String :: new( ) ,
101
- |mut acc: String , ( c1, c2) : ( char , Option <char >) | {
120
+ PyStringContent :: new( ) ,
121
+ |mut acc: PyStringContent , ( c1, c2) : ( PyStringCodePoint , Option <PyStringCodePoint >) | {
102
122
acc. push( c1) ;
103
123
match c2 { Some ( c) => acc. push( c) , None => ( ) } ;
104
124
acc
@@ -123,7 +143,7 @@ named!(pub string<StrSpan, PyString>,
123
143
| delimited!( char !( '\'' ) , call!( shortrawstring, '\'' ) , char !( '\'' ) )
124
144
| delimited!( char !( '"' ) , call!( shortrawstring, '"' ) , char !( '"' ) )
125
145
)
126
- ) >> ( PyString { prefix: prefix. to_string( ) , content: content. to_string ( ) } )
146
+ ) >> ( PyString { prefix: prefix. to_string( ) , content: content } )
127
147
)
128
148
) ;
129
149
0 commit comments