@@ -161,80 +161,89 @@ impl KdlEntry {
161
161
self . len ( ) == 0
162
162
}
163
163
164
+ /// Keeps the general entry formatting, though v1 entries will still be
165
+ /// updated to v2 while preserving as much as possible.
166
+ pub fn keep_format ( & mut self ) {
167
+ if let Some ( fmt) = self . format_mut ( ) {
168
+ fmt. autoformat_keep = true ;
169
+ }
170
+ }
171
+
164
172
/// Auto-formats this entry.
165
173
pub fn autoformat ( & mut self ) {
166
174
// TODO once MSRV allows:
167
175
//self.format.take_if(|f| !f.autoformat_keep);
168
- let value_repr = self . format . as_ref ( ) . map ( |x| {
169
- match & self . value {
170
- KdlValue :: String ( val) => {
171
- // cleanup. I don't _think_ this should have any whitespace,
172
- // but just in case.
173
- let s = x. value_repr . trim ( ) ;
174
- // convert raw strings to new format
175
- let s = s. strip_prefix ( 'r' ) . unwrap_or ( s) ;
176
- let s = if crate :: value:: is_plain_ident ( val) {
177
- val. to_string ( )
178
- } else if s
179
- . find ( |c| v2_parser:: NEWLINES . iter ( ) . any ( |nl| nl. contains ( c) ) )
180
- . is_some ( )
181
- {
182
- // Multiline string. Need triple quotes if they're not there already.
183
- if s. contains ( "\" \" \" " ) {
184
- // We're probably good. This could be more precise, but close enough.
185
- s. to_string ( )
186
- } else {
187
- // `"` -> `"""` but also extra newlines need to be
188
- // added because v2 strips the first and last ones.
189
- let s = s. replacen ( '\"' , "\" \" \" \n " , 1 ) ;
190
- s. chars ( )
191
- . rev ( )
192
- . collect :: < String > ( )
193
- . replacen ( '\"' , "\" \" \" \n " , 1 )
194
- . chars ( )
195
- . rev ( )
196
- . collect :: < String > ( )
197
- }
198
- } else if !s. starts_with ( '#' ) {
199
- // `/` is no longer an escaped char in v2.
200
- s. replace ( "\\ /" , "/" )
201
- } else {
202
- // We're all good! Let's move on.
203
- s. to_string ( )
204
- } ;
205
- s
206
- }
207
- // These have `#` prefixes now. The regular Display impl will
208
- // take care of that.
209
- KdlValue :: Bool ( _) | KdlValue :: Null => format ! ( "{}" , self . value) ,
210
- // These should be fine as-is?
211
- KdlValue :: Integer ( _) | KdlValue :: Float ( _) => x. value_repr . clone ( ) ,
212
- }
213
- } ) ;
214
-
176
+ let old_fmt = self . format . clone ( ) ;
215
177
if !self
216
178
. format
217
179
. as_ref ( )
218
180
. map ( |f| f. autoformat_keep )
219
181
. unwrap_or ( false )
220
182
{
221
183
self . format = None ;
222
- }
223
-
224
- if let Some ( value_repr) = value_repr. as_ref ( ) {
225
- self . format = Some (
226
- self . format
227
- . clone ( )
228
- . map ( |mut x| {
229
- x. value_repr = value_repr. into ( ) ;
230
- x
231
- } )
232
- . unwrap_or_else ( || KdlEntryFormat {
233
- value_repr : value_repr. into ( ) ,
234
- leading : " " . into ( ) ,
235
- ..Default :: default ( )
236
- } ) ,
237
- )
184
+ } else {
185
+ let value_repr = old_fmt. map ( |x| {
186
+ match & self . value {
187
+ KdlValue :: String ( val) => {
188
+ // cleanup. I don't _think_ this should have any whitespace,
189
+ // but just in case.
190
+ let s = x. value_repr . trim ( ) ;
191
+ // convert raw strings to new format
192
+ let s = s. strip_prefix ( 'r' ) . unwrap_or ( s) ;
193
+ let s = if crate :: value:: is_plain_ident ( val) {
194
+ val. to_string ( )
195
+ } else if s
196
+ . find ( |c| v2_parser:: NEWLINES . iter ( ) . any ( |nl| nl. contains ( c) ) )
197
+ . is_some ( )
198
+ {
199
+ // Multiline string. Need triple quotes if they're not there already.
200
+ if s. contains ( "\" \" \" " ) {
201
+ // We're probably good. This could be more precise, but close enough.
202
+ s. to_string ( )
203
+ } else {
204
+ // `"` -> `"""` but also extra newlines need to be
205
+ // added because v2 strips the first and last ones.
206
+ let s = s. replacen ( '\"' , "\" \" \" \n " , 1 ) ;
207
+ s. chars ( )
208
+ . rev ( )
209
+ . collect :: < String > ( )
210
+ . replacen ( '\"' , "\" \" \" \n " , 1 )
211
+ . chars ( )
212
+ . rev ( )
213
+ . collect :: < String > ( )
214
+ }
215
+ } else if !s. starts_with ( '#' ) {
216
+ // `/` is no longer an escaped char in v2.
217
+ s. replace ( "\\ /" , "/" )
218
+ } else {
219
+ // We're all good! Let's move on.
220
+ s. to_string ( )
221
+ } ;
222
+ s
223
+ }
224
+ // These have `#` prefixes now. The regular Display impl will
225
+ // take care of that.
226
+ KdlValue :: Bool ( _) | KdlValue :: Null => format ! ( "{}" , self . value) ,
227
+ // These should be fine as-is?
228
+ KdlValue :: Integer ( _) | KdlValue :: Float ( _) => x. value_repr . clone ( ) ,
229
+ }
230
+ } ) ;
231
+
232
+ if let Some ( value_repr) = value_repr. as_ref ( ) {
233
+ self . format = Some (
234
+ self . format
235
+ . clone ( )
236
+ . map ( |mut x| {
237
+ x. value_repr = value_repr. into ( ) ;
238
+ x
239
+ } )
240
+ . unwrap_or_else ( || KdlEntryFormat {
241
+ value_repr : value_repr. into ( ) ,
242
+ leading : " " . into ( ) ,
243
+ ..Default :: default ( )
244
+ } ) ,
245
+ )
246
+ }
238
247
}
239
248
240
249
if let Some ( name) = & mut self . name {
@@ -523,42 +532,52 @@ mod test {
523
532
#[ test]
524
533
fn v1_to_v2_format ( ) -> miette:: Result < ( ) > {
525
534
let mut entry = KdlEntry :: parse_v1 ( r##"r#"hello, world!"#"## ) ?;
535
+ entry. keep_format ( ) ;
526
536
entry. autoformat ( ) ;
527
537
assert_eq ! ( format!( "{}" , entry) , r##" #"hello, world!"#"## ) ;
528
538
529
539
let mut entry = KdlEntry :: parse_v1 ( r#""hello, \" world!""# ) ?;
540
+ entry. keep_format ( ) ;
530
541
entry. autoformat ( ) ;
531
542
assert_eq ! ( format!( "{}" , entry) , r#" "hello, \" world!""# ) ;
532
543
533
544
let mut entry = KdlEntry :: parse_v1 ( "\" foo!`~.,<>\" " ) ?;
545
+ entry. keep_format ( ) ;
534
546
entry. autoformat ( ) ;
535
547
assert_eq ! ( format!( "{}" , entry) , " foo!`~.,<>" ) ;
536
548
537
549
let mut entry = KdlEntry :: parse_v1 ( "\" \n hello, world!\" " ) ?;
550
+ entry. keep_format ( ) ;
538
551
entry. autoformat ( ) ;
539
552
assert_eq ! ( format!( "{}" , entry) , " \" \" \" \n \n hello, world!\n \" \" \" " ) ;
540
553
541
554
let mut entry = KdlEntry :: parse_v1 ( "r#\" \n hello, world!\" #" ) ?;
555
+ entry. keep_format ( ) ;
542
556
entry. autoformat ( ) ;
543
557
assert_eq ! ( format!( "{}" , entry) , " #\" \" \" \n \n hello, world!\n \" \" \" #" ) ;
544
558
545
559
let mut entry = KdlEntry :: parse_v1 ( "true" ) ?;
560
+ entry. keep_format ( ) ;
546
561
entry. autoformat ( ) ;
547
562
assert_eq ! ( format!( "{}" , entry) , " #true" ) ;
548
563
549
564
let mut entry = KdlEntry :: parse_v1 ( "false" ) ?;
565
+ entry. keep_format ( ) ;
550
566
entry. autoformat ( ) ;
551
567
assert_eq ! ( format!( "{}" , entry) , " #false" ) ;
552
568
553
569
let mut entry = KdlEntry :: parse_v1 ( "null" ) ?;
570
+ entry. keep_format ( ) ;
554
571
entry. autoformat ( ) ;
555
572
assert_eq ! ( format!( "{}" , entry) , " #null" ) ;
556
573
557
574
let mut entry = KdlEntry :: parse_v1 ( "1_234_567" ) ?;
575
+ entry. keep_format ( ) ;
558
576
entry. autoformat ( ) ;
559
577
assert_eq ! ( format!( "{}" , entry) , " 1_234_567" ) ;
560
578
561
579
let mut entry = KdlEntry :: parse_v1 ( "1_234_567E-10" ) ?;
580
+ entry. keep_format ( ) ;
562
581
entry. autoformat ( ) ;
563
582
assert_eq ! ( format!( "{}" , entry) , " 1_234_567E-10" ) ;
564
583
Ok ( ( ) )
0 commit comments