@@ -46,12 +46,44 @@ impl ast::FnDef {
4646 }
4747}
4848
49+ fn make_multiline < N > ( node : N ) -> N
50+ where
51+ N : AstNode + Clone ,
52+ {
53+ let l_curly = match node. syntax ( ) . children_with_tokens ( ) . find ( |it| it. kind ( ) == T ! [ '{' ] ) {
54+ Some ( it) => it,
55+ None => return node,
56+ } ;
57+ let sibling = match l_curly. next_sibling_or_token ( ) {
58+ Some ( it) => it,
59+ None => return node,
60+ } ;
61+ let existing_ws = match sibling. as_token ( ) {
62+ None => None ,
63+ Some ( tok) if tok. kind ( ) != WHITESPACE => None ,
64+ Some ( ws) => {
65+ if ws. text ( ) . contains ( '\n' ) {
66+ return node;
67+ }
68+ Some ( ws. clone ( ) )
69+ }
70+ } ;
71+
72+ let indent = leading_indent ( node. syntax ( ) ) . unwrap_or_default ( ) ;
73+ let ws = tokens:: WsBuilder :: new ( & format ! ( "\n {}" , indent) ) ;
74+ let to_insert = iter:: once ( ws. ws ( ) . into ( ) ) ;
75+ match existing_ws {
76+ None => node. insert_children ( InsertPosition :: After ( l_curly) , to_insert) ,
77+ Some ( ws) => node. replace_children ( single_node ( ws) , to_insert) ,
78+ }
79+ }
80+
4981impl ast:: ItemList {
5082 #[ must_use]
5183 pub fn append_items ( & self , items : impl Iterator < Item = ast:: ImplItem > ) -> ast:: ItemList {
5284 let mut res = self . clone ( ) ;
5385 if !self . syntax ( ) . text ( ) . contains_char ( '\n' ) {
54- res = res . make_multiline ( ) ;
86+ res = make_multiline ( res ) ;
5587 }
5688 items. for_each ( |it| res = res. append_item ( it) ) ;
5789 res
@@ -81,35 +113,6 @@ impl ast::ItemList {
81113 fn l_curly ( & self ) -> Option < SyntaxElement > {
82114 self . syntax ( ) . children_with_tokens ( ) . find ( |it| it. kind ( ) == T ! [ '{' ] )
83115 }
84-
85- fn make_multiline ( & self ) -> ast:: ItemList {
86- let l_curly = match self . syntax ( ) . children_with_tokens ( ) . find ( |it| it. kind ( ) == T ! [ '{' ] ) {
87- Some ( it) => it,
88- None => return self . clone ( ) ,
89- } ;
90- let sibling = match l_curly. next_sibling_or_token ( ) {
91- Some ( it) => it,
92- None => return self . clone ( ) ,
93- } ;
94- let existing_ws = match sibling. as_token ( ) {
95- None => None ,
96- Some ( tok) if tok. kind ( ) != WHITESPACE => None ,
97- Some ( ws) => {
98- if ws. text ( ) . contains ( '\n' ) {
99- return self . clone ( ) ;
100- }
101- Some ( ws. clone ( ) )
102- }
103- } ;
104-
105- let indent = leading_indent ( self . syntax ( ) ) . unwrap_or_default ( ) ;
106- let ws = tokens:: WsBuilder :: new ( & format ! ( "\n {}" , indent) ) ;
107- let to_insert = iter:: once ( ws. ws ( ) . into ( ) ) ;
108- match existing_ws {
109- None => self . insert_children ( InsertPosition :: After ( l_curly) , to_insert) ,
110- Some ( ws) => self . replace_children ( single_node ( ws) , to_insert) ,
111- }
112- }
113116}
114117
115118impl ast:: RecordFieldList {
@@ -334,6 +337,69 @@ impl ast::UseTree {
334337 }
335338}
336339
340+ impl ast:: MatchArmList {
341+ #[ must_use]
342+ pub fn append_arms ( & self , items : impl Iterator < Item = ast:: MatchArm > ) -> ast:: MatchArmList {
343+ let mut res = self . clone ( ) ;
344+ res = res. strip_if_only_whitespace ( ) ;
345+ if !res. syntax ( ) . text ( ) . contains_char ( '\n' ) {
346+ res = make_multiline ( res) ;
347+ }
348+ items. for_each ( |it| res = res. append_arm ( it) ) ;
349+ res
350+ }
351+
352+ fn strip_if_only_whitespace ( & self ) -> ast:: MatchArmList {
353+ let mut iter = self . syntax ( ) . children_with_tokens ( ) . skip_while ( |it| it. kind ( ) != T ! [ '{' ] ) ;
354+ iter. next ( ) ; // Eat the curly
355+ let mut inner = iter. take_while ( |it| it. kind ( ) != T ! [ '}' ] ) ;
356+ if !inner. clone ( ) . all ( |it| it. kind ( ) == WHITESPACE ) {
357+ return self . clone ( ) ;
358+ }
359+ let start = match inner. next ( ) {
360+ Some ( s) => s,
361+ None => return self . clone ( ) ,
362+ } ;
363+ let end = match inner. last ( ) {
364+ Some ( s) => s,
365+ None => start. clone ( ) ,
366+ } ;
367+ self . replace_children ( start..=end, & mut iter:: empty ( ) )
368+ }
369+
370+ #[ must_use]
371+ pub fn remove_placeholder ( & self ) -> ast:: MatchArmList {
372+ let placeholder = self . arms ( ) . find ( |arm| {
373+ if let Some ( ast:: Pat :: PlaceholderPat ( _) ) = arm. pat ( ) {
374+ return true ;
375+ }
376+ false
377+ } ) ;
378+ if let Some ( placeholder) = placeholder {
379+ let s: SyntaxElement = placeholder. syntax ( ) . clone ( ) . into ( ) ;
380+ let e = s. clone ( ) ;
381+ self . replace_children ( s..=e, & mut iter:: empty ( ) )
382+ } else {
383+ self . clone ( )
384+ }
385+ }
386+
387+ #[ must_use]
388+ pub fn append_arm ( & self , item : ast:: MatchArm ) -> ast:: MatchArmList {
389+ let r_curly = match self . syntax ( ) . children_with_tokens ( ) . find ( |it| it. kind ( ) == T ! [ '}' ] ) {
390+ Some ( t) => t,
391+ None => return self . clone ( ) ,
392+ } ;
393+ let position = InsertPosition :: Before ( r_curly. into ( ) ) ;
394+ let arm_ws = tokens:: WsBuilder :: new ( " " ) ;
395+ let match_indent = & leading_indent ( self . syntax ( ) ) . unwrap_or_default ( ) ;
396+ let match_ws = tokens:: WsBuilder :: new ( & format ! ( "\n {}" , match_indent) ) ;
397+ let to_insert: ArrayVec < [ SyntaxElement ; 3 ] > =
398+ [ arm_ws. ws ( ) . into ( ) , item. syntax ( ) . clone ( ) . into ( ) , match_ws. ws ( ) . into ( ) ] . into ( ) ;
399+ self . insert_children ( position, to_insert)
400+ }
401+ }
402+
337403#[ must_use]
338404pub fn remove_attrs_and_docs < N : ast:: AttrsOwner > ( node : & N ) -> N {
339405 N :: cast ( remove_attrs_and_docs_inner ( node. syntax ( ) . clone ( ) ) ) . unwrap ( )
0 commit comments