@@ -15,20 +15,32 @@ use lists::{format_item_list, itemize_list};
1515use expr:: { rewrite_unary_prefix, rewrite_pair, rewrite_tuple} ;
1616use types:: rewrite_path;
1717
18- use syntax:: ast:: { BindingMode , Pat , Pat_ } ;
18+ use syntax:: ast:: { BindingMode , Pat , Pat_ , FieldPat } ;
1919
20- // FIXME(#18): implement pattern formatting.
2120impl Rewrite for Pat {
2221 fn rewrite ( & self , context : & RewriteContext , width : usize , offset : Indent ) -> Option < String > {
2322 match self . node {
2423 Pat_ :: PatBox ( ref pat) => rewrite_unary_prefix ( context, "box " , & * * pat, width, offset) ,
25- Pat_ :: PatIdent ( binding_mode, ident, None ) => {
24+ Pat_ :: PatIdent ( binding_mode, ident, ref sub_pat ) => {
2625 let ( prefix, mutability) = match binding_mode {
2726 BindingMode :: BindByRef ( mutability) => ( "ref " , mutability) ,
2827 BindingMode :: BindByValue ( mutability) => ( "" , mutability) ,
2928 } ;
3029 let mut_infix = format_mutability ( mutability) ;
31- let result = format ! ( "{}{}{}" , prefix, mut_infix, ident. node) ;
30+ let id_str = ident. node . to_string ( ) ;
31+
32+ let sub_pat = match * sub_pat {
33+ Some ( ref p) => {
34+ // 3 - ` @ `.
35+ let width = try_opt ! ( width. checked_sub( prefix. len( ) + mut_infix. len( ) +
36+ id_str. len( ) +
37+ 3 ) ) ;
38+ format ! ( " @ {}" , try_opt!( p. rewrite( context, width, offset) ) )
39+ }
40+ None => "" . to_owned ( ) ,
41+ } ;
42+
43+ let result = format ! ( "{}{}{}{}" , prefix, mut_infix, id_str, sub_pat) ;
3244 wrap_str ( result, context. config . max_width , width, offset)
3345 }
3446 Pat_ :: PatWild => {
@@ -55,39 +67,106 @@ impl Rewrite for Pat {
5567 width,
5668 offset)
5769 }
58- Pat_ :: PatEnum ( ref path, Some ( ref pat_vec) ) => {
59- let path_str = try_opt ! ( :: types:: rewrite_path( context,
60- true ,
61- None ,
62- path,
63- width,
64- offset) ) ;
70+ Pat_ :: PatEnum ( ref path, ref pat_vec) => {
71+ let path_str = try_opt ! ( rewrite_path( context, true , None , path, width, offset) ) ;
6572
66- if pat_vec. is_empty ( ) {
67- Some ( path_str)
68- } else {
69- // 1 = (
70- let width = try_opt ! ( width. checked_sub( path_str. len( ) + 1 ) ) ;
71- let offset = offset + path_str. len ( ) + 1 ;
72- let items = itemize_list ( context. codemap ,
73- pat_vec. iter ( ) ,
74- ")" ,
75- |item| item. span . lo ,
76- |item| item. span . hi ,
77- |item| item. rewrite ( context, width, offset) ,
78- span_after ( self . span , "(" , context. codemap ) ,
79- self . span . hi ) ;
80- Some ( format ! ( "{}({})" ,
81- path_str,
82- try_opt!( format_item_list( items, width, offset, context. config) ) ) )
73+ match * pat_vec {
74+ Some ( ref pat_vec) => {
75+ if pat_vec. is_empty ( ) {
76+ Some ( path_str)
77+ } else {
78+ // 1 = (
79+ let width = try_opt ! ( width. checked_sub( path_str. len( ) + 1 ) ) ;
80+ let offset = offset + path_str. len ( ) + 1 ;
81+ let items = itemize_list ( context. codemap ,
82+ pat_vec. iter ( ) ,
83+ ")" ,
84+ |item| item. span . lo ,
85+ |item| item. span . hi ,
86+ |item| item. rewrite ( context, width, offset) ,
87+ span_after ( self . span , "(" , context. codemap ) ,
88+ self . span . hi ) ;
89+ Some ( format ! ( "{}({})" ,
90+ path_str,
91+ try_opt!( format_item_list( items,
92+ width,
93+ offset,
94+ context. config) ) ) )
95+ }
96+ }
97+ None => Some ( format ! ( "{}(..)" , path_str) ) ,
8398 }
8499 }
85100 Pat_ :: PatLit ( ref expr) => expr. rewrite ( context, width, offset) ,
86- // FIXME(#8): format remaining pattern variants.
87- Pat_ :: PatIdent ( _, _, Some ( ..) ) |
88- Pat_ :: PatEnum ( _, None ) |
89- Pat_ :: PatStruct ( ..) |
90- Pat_ :: PatVec ( ..) |
101+ Pat_ :: PatVec ( ref prefix, ref slice_pat, ref suffix) => {
102+ // Rewrite all the sub-patterns.
103+ let prefix = prefix. iter ( ) . map ( |p| p. rewrite ( context, width, offset) ) ;
104+ let slice_pat = slice_pat. as_ref ( ) . map ( |p| {
105+ Some ( format ! ( "{}.." , try_opt!( p. rewrite( context, width, offset) ) ) )
106+ } ) ;
107+ let suffix = suffix. iter ( ) . map ( |p| p. rewrite ( context, width, offset) ) ;
108+
109+ // Munge them together.
110+ let pats: Option < Vec < String > > = prefix. chain ( slice_pat. into_iter ( ) )
111+ . chain ( suffix)
112+ . collect ( ) ;
113+
114+ // Check that all the rewrites succeeded, and if not return None.
115+ let pats = try_opt ! ( pats) ;
116+
117+ // Unwrap all the sub-strings and join them with commas.
118+ let result = format ! ( "[{}]" , pats. join( ", " ) ) ;
119+ wrap_str ( result, context. config . max_width , width, offset)
120+ }
121+ Pat_ :: PatStruct ( ref path, ref fields, elipses) => {
122+ let path = try_opt ! ( rewrite_path( context, true , None , path, width, offset) ) ;
123+
124+ let ( elipses_str, terminator) = if elipses {
125+ ( ", .." , ".." )
126+ } else {
127+ ( "" , "}" )
128+ } ;
129+
130+ // 5 = `{` plus space before and after plus `}` plus space before.
131+ let budget = try_opt ! ( width. checked_sub( path. len( ) + 5 + elipses_str. len( ) ) ) ;
132+ // FIXME Using visual indenting, should use block or visual to match
133+ // struct lit preference (however, in practice I think it is rare
134+ // for struct patterns to be multi-line).
135+ // 3 = `{` plus space before and after.
136+ let offset = offset + path. len ( ) + 3 ;
137+
138+ let items = itemize_list ( context. codemap ,
139+ fields. iter ( ) ,
140+ terminator,
141+ |f| f. span . lo ,
142+ |f| f. span . hi ,
143+ |f| f. node . rewrite ( context, budget, offset) ,
144+ span_after ( self . span , "{" , context. codemap ) ,
145+ self . span . hi ) ;
146+ let mut field_string = try_opt ! ( format_item_list( items,
147+ budget,
148+ offset,
149+ context. config) ) ;
150+ if elipses {
151+ if field_string. contains ( '\n' ) {
152+ field_string. push_str ( ",\n " ) ;
153+ field_string. push_str ( & offset. to_string ( context. config ) ) ;
154+ field_string. push_str ( ".." ) ;
155+ } else {
156+ if field_string. len ( ) > 0 {
157+ field_string. push_str ( ", " ) ;
158+ }
159+ field_string. push_str ( ".." ) ;
160+ }
161+ }
162+
163+ if field_string. is_empty ( ) {
164+ Some ( format ! ( "{} {{}}" , path) )
165+ } else {
166+ Some ( format ! ( "{} {{ {} }}" , path, field_string) )
167+ }
168+ }
169+ // FIXME(#819) format pattern macros.
91170 Pat_ :: PatMac ( ..) => {
92171 wrap_str ( context. snippet ( self . span ) ,
93172 context. config . max_width ,
@@ -97,3 +176,17 @@ impl Rewrite for Pat {
97176 }
98177 }
99178}
179+
180+ impl Rewrite for FieldPat {
181+ fn rewrite ( & self , context : & RewriteContext , width : usize , offset : Indent ) -> Option < String > {
182+ let pat = self . pat . rewrite ( context, width, offset) ;
183+ if self . is_shorthand {
184+ pat
185+ } else {
186+ wrap_str ( format ! ( "{}: {}" , self . ident. to_string( ) , try_opt!( pat) ) ,
187+ context. config . max_width ,
188+ width,
189+ offset)
190+ }
191+ }
192+ }
0 commit comments