@@ -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,85 @@ 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+ let res = self . replace_children ( start..=end, & mut iter:: empty ( ) ) ;
368+ res
369+ }
370+
371+ #[ must_use]
372+ pub fn remove_placeholder ( & self ) -> ast:: MatchArmList {
373+ let placeholder = self . arms ( ) . find ( |arm| {
374+ if let Some ( ast:: Pat :: PlaceholderPat ( _) ) = arm. pat ( ) {
375+ return true ;
376+ }
377+ false
378+ } ) ;
379+ if let Some ( placeholder) = placeholder {
380+ let s: SyntaxElement = placeholder. syntax ( ) . clone ( ) . into ( ) ;
381+ let e = s. clone ( ) ;
382+ self . replace_children ( s..=e, & mut iter:: empty ( ) )
383+ } else {
384+ self . clone ( )
385+ }
386+ }
387+
388+ #[ must_use]
389+ pub fn append_arm ( & self , item : ast:: MatchArm ) -> ast:: MatchArmList {
390+ let r_curly = match self . syntax ( ) . children_with_tokens ( ) . find ( |it| it. kind ( ) == T ! [ '}' ] ) {
391+ Some ( t) => t,
392+ None => return self . clone ( ) ,
393+ } ;
394+ let mut sib = r_curly. prev_sibling_or_token ( ) ;
395+ while let Some ( s) = sib. clone ( ) {
396+ if let Some ( tok) = s. as_token ( ) {
397+ if tok. kind ( ) != WHITESPACE {
398+ break ;
399+ }
400+ sib = s. prev_sibling_or_token ( ) ;
401+ } else {
402+ break ;
403+ }
404+ }
405+ let indent = " " . to_string ( ) + & leading_indent ( self . syntax ( ) ) . unwrap_or_default ( ) ;
406+ let sib = match sib {
407+ Some ( s) => s,
408+ None => return self . clone ( ) ,
409+ } ;
410+ let position = InsertPosition :: After ( sib. into ( ) ) ;
411+ let ws = tokens:: WsBuilder :: new ( & format ! ( "\n {}" , indent) ) ;
412+ let to_insert: ArrayVec < [ SyntaxElement ; 2 ] > =
413+ [ ws. ws ( ) . into ( ) , item. syntax ( ) . clone ( ) . into ( ) ] . into ( ) ;
414+ let res = self . insert_children ( position, to_insert) ;
415+ res
416+ }
417+ }
418+
337419#[ must_use]
338420pub fn remove_attrs_and_docs < N : ast:: AttrsOwner > ( node : & N ) -> N {
339421 N :: cast ( remove_attrs_and_docs_inner ( node. syntax ( ) . clone ( ) ) ) . unwrap ( )
0 commit comments