11use nom:: anychar;
22
3+ #[ cfg( feature="wtf8" ) ]
4+ use wtf8;
5+
36use helpers:: StrSpan ;
47use ast:: * ;
58
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 >>,
727 preceded!( char !( '\\' ) ,
828 alt!(
929 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
2040 | tuple!( one_of!( "01234567" ) , opt!( one_of!( "01234567" ) ) , opt!( one_of!( "01234567" ) ) ) => { |( c1, c2, c3) : ( char , Option <char >, Option <char >) |
2141 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) ,
2545 _ => unreachable!( ) ,
2646 }
2747 }
2848 | preceded!( char !( 'x' ) , tuple!( one_of!( "0123456789abcdefABCDEF" ) , one_of!( "0123456789abcdefABCDEF" ) ) ) => { |( c1, c2) : ( char , char ) |
2949 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) ,
3151 _ => unreachable!( ) ,
3252 }
3353 }
@@ -38,14 +58,14 @@ named!(escapedchar<StrSpan, Option<char>>,
3858 | preceded!( char !( 'u' ) , count!( one_of!( "0123456789abcdefABCDEF" ) , 4 ) ) => { |v: Vec <char >| {
3959 let it: Vec <u32 > = v. iter( ) . map( |c| c. to_digit( 16 ) . unwrap( ) ) . collect( ) ;
4060 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)
4262 }
4363 else { unreachable!( ) }
4464 } }
4565 | preceded!( char !( 'U' ) , count!( one_of!( "0123456789abcdefABCDEF" ) , 8 ) ) => { |v: Vec <char >| {
4666 let it: Vec <u32 > = v. iter( ) . map( |c| c. to_digit( 16 ) . unwrap( ) ) . collect( ) ;
4767 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 ) +
4969 ( d5 << 12 ) + ( d6 << 8 ) + ( d7 << 4 ) + d8)
5070 }
5171 else { unreachable!( ) }
@@ -54,51 +74,51 @@ named!(escapedchar<StrSpan, Option<char>>,
5474 )
5575) ;
5676
57- named_args ! ( shortstring( quote: char ) <StrSpan , String >,
77+ named_args ! ( shortstring( quote: char ) <StrSpan , PyStringContent >,
5878 fold_many0!(
5979 alt!(
6080 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 ) ) }
6282 ) ,
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 }
6585 )
6686) ;
6787
68- named_args ! ( longstring( quote: char ) <StrSpan , String >,
88+ named_args ! ( longstring( quote: char ) <StrSpan , PyStringContent >,
6989 fold_many0!(
7090 alt!(
7191 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 ) ) }
7393 ) ,
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 }
7696 )
7797) ;
7898
79- named_args ! ( shortrawstring( quote: char ) <StrSpan , String >,
99+ named_args ! ( shortrawstring( quote: char ) <StrSpan , PyStringContent >,
80100 fold_many0!(
81101 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 ) }
84104 ) ,
85- String :: new( ) ,
86- |mut acc: String , ( c1, c2) : ( char , Option <char >) | {
105+ PyStringContent :: new( ) ,
106+ |mut acc: PyStringContent , ( c1, c2) : ( PyStringCodePoint , Option <PyStringCodePoint >) | {
87107 acc. push( c1) ;
88108 match c2 { Some ( c) => acc. push( c) , None => ( ) } ;
89109 acc
90110 }
91111 )
92112) ;
93113
94- named_args ! ( longrawstring( quote: char ) <StrSpan , String >,
114+ named_args ! ( longrawstring( quote: char ) <StrSpan , PyStringContent >,
95115 fold_many0!(
96116 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 ) }
99119 ) ,
100- String :: new( ) ,
101- |mut acc: String , ( c1, c2) : ( char , Option <char >) | {
120+ PyStringContent :: new( ) ,
121+ |mut acc: PyStringContent , ( c1, c2) : ( PyStringCodePoint , Option <PyStringCodePoint >) | {
102122 acc. push( c1) ;
103123 match c2 { Some ( c) => acc. push( c) , None => ( ) } ;
104124 acc
@@ -123,7 +143,7 @@ named!(pub string<StrSpan, PyString>,
123143 | delimited!( char !( '\'' ) , call!( shortrawstring, '\'' ) , char !( '\'' ) )
124144 | delimited!( char !( '"' ) , call!( shortrawstring, '"' ) , char !( '"' ) )
125145 )
126- ) >> ( PyString { prefix: prefix. to_string( ) , content: content. to_string ( ) } )
146+ ) >> ( PyString { prefix: prefix. to_string( ) , content: content } )
127147 )
128148) ;
129149
0 commit comments