148148//! CSV options like `quoteAll`. You can control when fields are quoted using the
149149//! [`QuoteStyle`] enum.
150150//!
151- //! ## Available Quoting Styles
152- //!
153- //! - `QuoteStyle::Necessary` (default): Only quotes fields when necessary (e.g., when they
154- //! contain delimiters, quotes, or newlines)
155- //! - `QuoteStyle::Always`: Quotes all fields (equivalent to Spark's `quoteAll=true`)
156- //! - `QuoteStyle::NonNumeric`: Quotes only non-numeric fields
157- //! - `QuoteStyle::Never`: Never quotes fields (warning: can produce invalid CSV)
158- //!
159- //! ## Example with quoting styles
151+ //! ## Example
160152//!
161153//! ```
162154//! # use arrow_array::*;
@@ -1287,6 +1279,31 @@ sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo
12871279 ) ;
12881280 }
12891281
1282+ fn write_quote_style ( batch : & RecordBatch , quote_style : QuoteStyle ) -> String {
1283+ let mut buf = Vec :: new ( ) ;
1284+ let mut writer = WriterBuilder :: new ( )
1285+ . with_quote_style ( quote_style)
1286+ . build ( & mut buf) ;
1287+ writer. write ( batch) . unwrap ( ) ;
1288+ drop ( writer) ;
1289+ String :: from_utf8 ( buf) . unwrap ( )
1290+ }
1291+
1292+ fn write_quote_style_with_null (
1293+ batch : & RecordBatch ,
1294+ quote_style : QuoteStyle ,
1295+ null_value : & str ,
1296+ ) -> String {
1297+ let mut buf = Vec :: new ( ) ;
1298+ let mut writer = WriterBuilder :: new ( )
1299+ . with_quote_style ( quote_style)
1300+ . with_null ( null_value. to_string ( ) )
1301+ . build ( & mut buf) ;
1302+ writer. write ( batch) . unwrap ( ) ;
1303+ drop ( writer) ;
1304+ String :: from_utf8 ( buf) . unwrap ( )
1305+ }
1306+
12901307 #[ test]
12911308 fn test_write_csv_quote_style ( ) {
12921309 let schema = Schema :: new ( vec ! [
@@ -1306,48 +1323,28 @@ sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo
13061323 . unwrap ( ) ;
13071324
13081325 // Test with QuoteStyle::Necessary (default)
1309- let mut buf = Vec :: new ( ) ;
1310- let builder = WriterBuilder :: new ( ) . with_quote_style ( QuoteStyle :: Necessary ) ;
1311- let mut writer = builder. build ( & mut buf) ;
1312- writer. write ( & batch) . unwrap ( ) ;
1313- drop ( writer) ;
13141326 assert_eq ! (
13151327 "text,number,float\n hello,1,1.1\n world,2,2.2\n \" comma,value\" ,3,3.3\n \" quote\" \" test\" ,4,4.4\n " ,
1316- String :: from_utf8 ( buf ) . unwrap ( )
1328+ write_quote_style ( & batch , QuoteStyle :: Necessary )
13171329 ) ;
13181330
13191331 // Test with QuoteStyle::Always (equivalent to Spark's quoteAll=true)
1320- let mut buf = Vec :: new ( ) ;
1321- let builder = WriterBuilder :: new ( ) . with_quote_style ( QuoteStyle :: Always ) ;
1322- let mut writer = builder. build ( & mut buf) ;
1323- writer. write ( & batch) . unwrap ( ) ;
1324- drop ( writer) ;
13251332 assert_eq ! (
13261333 "\" text\" ,\" number\" ,\" float\" \n \" hello\" ,\" 1\" ,\" 1.1\" \n \" world\" ,\" 2\" ,\" 2.2\" \n \" comma,value\" ,\" 3\" ,\" 3.3\" \n \" quote\" \" test\" ,\" 4\" ,\" 4.4\" \n " ,
1327- String :: from_utf8 ( buf ) . unwrap ( )
1334+ write_quote_style ( & batch , QuoteStyle :: Always )
13281335 ) ;
13291336
13301337 // Test with QuoteStyle::NonNumeric
1331- let mut buf = Vec :: new ( ) ;
1332- let builder = WriterBuilder :: new ( ) . with_quote_style ( QuoteStyle :: NonNumeric ) ;
1333- let mut writer = builder. build ( & mut buf) ;
1334- writer. write ( & batch) . unwrap ( ) ;
1335- drop ( writer) ;
13361338 assert_eq ! (
13371339 "\" text\" ,\" number\" ,\" float\" \n \" hello\" ,1,1.1\n \" world\" ,2,2.2\n \" comma,value\" ,3,3.3\n \" quote\" \" test\" ,4,4.4\n " ,
1338- String :: from_utf8 ( buf ) . unwrap ( )
1340+ write_quote_style ( & batch , QuoteStyle :: NonNumeric )
13391341 ) ;
13401342
13411343 // Test with QuoteStyle::Never (warning: can produce invalid CSV)
1342- let mut buf = Vec :: new ( ) ;
1343- let builder = WriterBuilder :: new ( ) . with_quote_style ( QuoteStyle :: Never ) ;
1344- let mut writer = builder. build ( & mut buf) ;
1345- writer. write ( & batch) . unwrap ( ) ;
1346- drop ( writer) ;
13471344 // Note: This produces invalid CSV for fields with commas or quotes
13481345 assert_eq ! (
13491346 "text,number,float\n hello,1,1.1\n world,2,2.2\n comma,value,3,3.3\n quote\" test,4,4.4\n " ,
1350- String :: from_utf8 ( buf ) . unwrap ( )
1347+ write_quote_style ( & batch , QuoteStyle :: Never )
13511348 ) ;
13521349 }
13531350
@@ -1365,27 +1362,15 @@ sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo
13651362 RecordBatch :: try_new ( Arc :: new ( schema) , vec ! [ Arc :: new( text) , Arc :: new( number) ] ) . unwrap ( ) ;
13661363
13671364 // Test with QuoteStyle::Always
1368- let mut buf = Vec :: new ( ) ;
1369- let builder = WriterBuilder :: new ( ) . with_quote_style ( QuoteStyle :: Always ) ;
1370- let mut writer = builder. build ( & mut buf) ;
1371- writer. write ( & batch) . unwrap ( ) ;
1372- drop ( writer) ;
13731365 assert_eq ! (
13741366 "\" text\" ,\" number\" \n \" hello\" ,\" 1\" \n \" \" ,\" 2\" \n \" world\" ,\" \" \n " ,
1375- String :: from_utf8 ( buf ) . unwrap ( )
1367+ write_quote_style ( & batch , QuoteStyle :: Always )
13761368 ) ;
13771369
13781370 // Test with QuoteStyle::Always and custom null value
1379- let mut buf = Vec :: new ( ) ;
1380- let builder = WriterBuilder :: new ( )
1381- . with_quote_style ( QuoteStyle :: Always )
1382- . with_null ( "NULL" . to_string ( ) ) ;
1383- let mut writer = builder. build ( & mut buf) ;
1384- writer. write ( & batch) . unwrap ( ) ;
1385- drop ( writer) ;
13861371 assert_eq ! (
13871372 "\" text\" ,\" number\" \n \" hello\" ,\" 1\" \n \" NULL\" ,\" 2\" \n \" world\" ,\" NULL\" \n " ,
1388- String :: from_utf8 ( buf ) . unwrap ( )
1373+ write_quote_style_with_null ( & batch , QuoteStyle :: Always , "NULL" )
13891374 ) ;
13901375 }
13911376}
0 commit comments