patchwork_csv_utils 0.1.1-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d1a370861f917ee057b3bb549db100e421ee0eb2663eddd45ec6360f2aa70906
4
+ data.tar.gz: c7b2b0a43957d5fedc5706aeb9f2948d4428020207ed51830fd0fba454b8267b
5
+ SHA512:
6
+ metadata.gz: bd712a3ebe8b07a0e67d748fe5b07f4824d38d22e115555198a9f459c3a2a806d2d6ca07085bd4044e185eff20afcb23d01805a4067c013076180e61fca8e56a
7
+ data.tar.gz: 30152a72b594333c2a9e10038a3133d249a8d76b0d62d69457ecf0a0d2ad93767642446747674e9855456386308c33d75970aa2c5470ea3e71dedf0d7a5e8119
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,30 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ SuggestExtensions: false
4
+ NewCops: enable
5
+
6
+ Style/StringLiterals:
7
+ Enabled: true
8
+ EnforcedStyle: single_quotes
9
+
10
+ Style/Documentation:
11
+ Enabled: false
12
+
13
+ Style/StringLiteralsInInterpolation:
14
+ Enabled: true
15
+ EnforcedStyle: double_quotes
16
+
17
+ Layout/LineLength:
18
+ Max: 120
19
+
20
+ Metrics/BlockLength:
21
+ Max: 120
22
+
23
+ Gemspec/RequireMFA:
24
+ Enabled: false
25
+
26
+
27
+
28
+
29
+
30
+
data/Cargo.lock ADDED
@@ -0,0 +1,808 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "adler"
7
+ version = "1.0.2"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
10
+
11
+ [[package]]
12
+ name = "aho-corasick"
13
+ version = "1.1.3"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
16
+ dependencies = [
17
+ "memchr",
18
+ ]
19
+
20
+ [[package]]
21
+ name = "android-tzdata"
22
+ version = "0.1.1"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
25
+
26
+ [[package]]
27
+ name = "android_system_properties"
28
+ version = "0.1.5"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
31
+ dependencies = [
32
+ "libc",
33
+ ]
34
+
35
+ [[package]]
36
+ name = "arbitrary"
37
+ version = "1.3.2"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+ checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
40
+ dependencies = [
41
+ "derive_arbitrary",
42
+ ]
43
+
44
+ [[package]]
45
+ name = "autocfg"
46
+ version = "1.3.0"
47
+ source = "registry+https://github.com/rust-lang/crates.io-index"
48
+ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
49
+
50
+ [[package]]
51
+ name = "bindgen"
52
+ version = "0.69.4"
53
+ source = "registry+https://github.com/rust-lang/crates.io-index"
54
+ checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
55
+ dependencies = [
56
+ "bitflags",
57
+ "cexpr",
58
+ "clang-sys",
59
+ "itertools",
60
+ "lazy_static",
61
+ "lazycell",
62
+ "proc-macro2",
63
+ "quote",
64
+ "regex",
65
+ "rustc-hash",
66
+ "shlex",
67
+ "syn",
68
+ ]
69
+
70
+ [[package]]
71
+ name = "bitflags"
72
+ version = "2.6.0"
73
+ source = "registry+https://github.com/rust-lang/crates.io-index"
74
+ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
75
+
76
+ [[package]]
77
+ name = "bumpalo"
78
+ version = "3.16.0"
79
+ source = "registry+https://github.com/rust-lang/crates.io-index"
80
+ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
81
+
82
+ [[package]]
83
+ name = "byteorder"
84
+ version = "1.5.0"
85
+ source = "registry+https://github.com/rust-lang/crates.io-index"
86
+ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
87
+
88
+ [[package]]
89
+ name = "calamine"
90
+ version = "0.25.0"
91
+ source = "registry+https://github.com/rust-lang/crates.io-index"
92
+ checksum = "58785077b99914cfa7aa07b7203b1d5eb91efcd7d5ffd0f51a98b95c36112ef4"
93
+ dependencies = [
94
+ "byteorder",
95
+ "chrono",
96
+ "codepage",
97
+ "encoding_rs",
98
+ "log",
99
+ "quick-xml",
100
+ "serde",
101
+ "zip",
102
+ ]
103
+
104
+ [[package]]
105
+ name = "cc"
106
+ version = "1.1.7"
107
+ source = "registry+https://github.com/rust-lang/crates.io-index"
108
+ checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
109
+
110
+ [[package]]
111
+ name = "cexpr"
112
+ version = "0.6.0"
113
+ source = "registry+https://github.com/rust-lang/crates.io-index"
114
+ checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
115
+ dependencies = [
116
+ "nom",
117
+ ]
118
+
119
+ [[package]]
120
+ name = "cfg-if"
121
+ version = "1.0.0"
122
+ source = "registry+https://github.com/rust-lang/crates.io-index"
123
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
124
+
125
+ [[package]]
126
+ name = "chrono"
127
+ version = "0.4.38"
128
+ source = "registry+https://github.com/rust-lang/crates.io-index"
129
+ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
130
+ dependencies = [
131
+ "android-tzdata",
132
+ "iana-time-zone",
133
+ "js-sys",
134
+ "num-traits",
135
+ "serde",
136
+ "wasm-bindgen",
137
+ "windows-targets",
138
+ ]
139
+
140
+ [[package]]
141
+ name = "clang-sys"
142
+ version = "1.8.1"
143
+ source = "registry+https://github.com/rust-lang/crates.io-index"
144
+ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
145
+ dependencies = [
146
+ "glob",
147
+ "libc",
148
+ "libloading",
149
+ ]
150
+
151
+ [[package]]
152
+ name = "codepage"
153
+ version = "0.1.2"
154
+ source = "registry+https://github.com/rust-lang/crates.io-index"
155
+ checksum = "48f68d061bc2828ae826206326e61251aca94c1e4a5305cf52d9138639c918b4"
156
+ dependencies = [
157
+ "encoding_rs",
158
+ ]
159
+
160
+ [[package]]
161
+ name = "core-foundation-sys"
162
+ version = "0.8.6"
163
+ source = "registry+https://github.com/rust-lang/crates.io-index"
164
+ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
165
+
166
+ [[package]]
167
+ name = "crc32fast"
168
+ version = "1.4.2"
169
+ source = "registry+https://github.com/rust-lang/crates.io-index"
170
+ checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
171
+ dependencies = [
172
+ "cfg-if",
173
+ ]
174
+
175
+ [[package]]
176
+ name = "crossbeam-utils"
177
+ version = "0.8.20"
178
+ source = "registry+https://github.com/rust-lang/crates.io-index"
179
+ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
180
+
181
+ [[package]]
182
+ name = "csv"
183
+ version = "1.3.0"
184
+ source = "registry+https://github.com/rust-lang/crates.io-index"
185
+ checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
186
+ dependencies = [
187
+ "csv-core",
188
+ "itoa",
189
+ "ryu",
190
+ "serde",
191
+ ]
192
+
193
+ [[package]]
194
+ name = "csv-core"
195
+ version = "0.1.11"
196
+ source = "registry+https://github.com/rust-lang/crates.io-index"
197
+ checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
198
+ dependencies = [
199
+ "memchr",
200
+ ]
201
+
202
+ [[package]]
203
+ name = "csv_utils"
204
+ version = "0.1.0"
205
+ dependencies = [
206
+ "calamine",
207
+ "chrono",
208
+ "csv",
209
+ "magnus",
210
+ ]
211
+
212
+ [[package]]
213
+ name = "derive_arbitrary"
214
+ version = "1.3.2"
215
+ source = "registry+https://github.com/rust-lang/crates.io-index"
216
+ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
217
+ dependencies = [
218
+ "proc-macro2",
219
+ "quote",
220
+ "syn",
221
+ ]
222
+
223
+ [[package]]
224
+ name = "displaydoc"
225
+ version = "0.2.5"
226
+ source = "registry+https://github.com/rust-lang/crates.io-index"
227
+ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
228
+ dependencies = [
229
+ "proc-macro2",
230
+ "quote",
231
+ "syn",
232
+ ]
233
+
234
+ [[package]]
235
+ name = "either"
236
+ version = "1.13.0"
237
+ source = "registry+https://github.com/rust-lang/crates.io-index"
238
+ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
239
+
240
+ [[package]]
241
+ name = "encoding_rs"
242
+ version = "0.8.34"
243
+ source = "registry+https://github.com/rust-lang/crates.io-index"
244
+ checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
245
+ dependencies = [
246
+ "cfg-if",
247
+ ]
248
+
249
+ [[package]]
250
+ name = "equivalent"
251
+ version = "1.0.1"
252
+ source = "registry+https://github.com/rust-lang/crates.io-index"
253
+ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
254
+
255
+ [[package]]
256
+ name = "flate2"
257
+ version = "1.0.30"
258
+ source = "registry+https://github.com/rust-lang/crates.io-index"
259
+ checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
260
+ dependencies = [
261
+ "crc32fast",
262
+ "miniz_oxide",
263
+ ]
264
+
265
+ [[package]]
266
+ name = "glob"
267
+ version = "0.3.1"
268
+ source = "registry+https://github.com/rust-lang/crates.io-index"
269
+ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
270
+
271
+ [[package]]
272
+ name = "hashbrown"
273
+ version = "0.14.5"
274
+ source = "registry+https://github.com/rust-lang/crates.io-index"
275
+ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
276
+
277
+ [[package]]
278
+ name = "iana-time-zone"
279
+ version = "0.1.60"
280
+ source = "registry+https://github.com/rust-lang/crates.io-index"
281
+ checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
282
+ dependencies = [
283
+ "android_system_properties",
284
+ "core-foundation-sys",
285
+ "iana-time-zone-haiku",
286
+ "js-sys",
287
+ "wasm-bindgen",
288
+ "windows-core",
289
+ ]
290
+
291
+ [[package]]
292
+ name = "iana-time-zone-haiku"
293
+ version = "0.1.2"
294
+ source = "registry+https://github.com/rust-lang/crates.io-index"
295
+ checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
296
+ dependencies = [
297
+ "cc",
298
+ ]
299
+
300
+ [[package]]
301
+ name = "indexmap"
302
+ version = "2.2.6"
303
+ source = "registry+https://github.com/rust-lang/crates.io-index"
304
+ checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
305
+ dependencies = [
306
+ "equivalent",
307
+ "hashbrown",
308
+ ]
309
+
310
+ [[package]]
311
+ name = "itertools"
312
+ version = "0.12.1"
313
+ source = "registry+https://github.com/rust-lang/crates.io-index"
314
+ checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
315
+ dependencies = [
316
+ "either",
317
+ ]
318
+
319
+ [[package]]
320
+ name = "itoa"
321
+ version = "1.0.11"
322
+ source = "registry+https://github.com/rust-lang/crates.io-index"
323
+ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
324
+
325
+ [[package]]
326
+ name = "js-sys"
327
+ version = "0.3.69"
328
+ source = "registry+https://github.com/rust-lang/crates.io-index"
329
+ checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
330
+ dependencies = [
331
+ "wasm-bindgen",
332
+ ]
333
+
334
+ [[package]]
335
+ name = "lazy_static"
336
+ version = "1.5.0"
337
+ source = "registry+https://github.com/rust-lang/crates.io-index"
338
+ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
339
+
340
+ [[package]]
341
+ name = "lazycell"
342
+ version = "1.3.0"
343
+ source = "registry+https://github.com/rust-lang/crates.io-index"
344
+ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
345
+
346
+ [[package]]
347
+ name = "libc"
348
+ version = "0.2.155"
349
+ source = "registry+https://github.com/rust-lang/crates.io-index"
350
+ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
351
+
352
+ [[package]]
353
+ name = "libloading"
354
+ version = "0.8.4"
355
+ source = "registry+https://github.com/rust-lang/crates.io-index"
356
+ checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
357
+ dependencies = [
358
+ "cfg-if",
359
+ "windows-targets",
360
+ ]
361
+
362
+ [[package]]
363
+ name = "log"
364
+ version = "0.4.22"
365
+ source = "registry+https://github.com/rust-lang/crates.io-index"
366
+ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
367
+
368
+ [[package]]
369
+ name = "magnus"
370
+ version = "0.7.1"
371
+ source = "registry+https://github.com/rust-lang/crates.io-index"
372
+ checksum = "3d87ae53030f3a22e83879e666cb94e58a7bdf31706878a0ba48752994146dab"
373
+ dependencies = [
374
+ "magnus-macros",
375
+ "rb-sys",
376
+ "rb-sys-env",
377
+ "seq-macro",
378
+ ]
379
+
380
+ [[package]]
381
+ name = "magnus-macros"
382
+ version = "0.6.0"
383
+ source = "registry+https://github.com/rust-lang/crates.io-index"
384
+ checksum = "5968c820e2960565f647819f5928a42d6e874551cab9d88d75e3e0660d7f71e3"
385
+ dependencies = [
386
+ "proc-macro2",
387
+ "quote",
388
+ "syn",
389
+ ]
390
+
391
+ [[package]]
392
+ name = "memchr"
393
+ version = "2.7.4"
394
+ source = "registry+https://github.com/rust-lang/crates.io-index"
395
+ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
396
+
397
+ [[package]]
398
+ name = "minimal-lexical"
399
+ version = "0.2.1"
400
+ source = "registry+https://github.com/rust-lang/crates.io-index"
401
+ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
402
+
403
+ [[package]]
404
+ name = "miniz_oxide"
405
+ version = "0.7.4"
406
+ source = "registry+https://github.com/rust-lang/crates.io-index"
407
+ checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
408
+ dependencies = [
409
+ "adler",
410
+ ]
411
+
412
+ [[package]]
413
+ name = "nom"
414
+ version = "7.1.3"
415
+ source = "registry+https://github.com/rust-lang/crates.io-index"
416
+ checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
417
+ dependencies = [
418
+ "memchr",
419
+ "minimal-lexical",
420
+ ]
421
+
422
+ [[package]]
423
+ name = "num-traits"
424
+ version = "0.2.19"
425
+ source = "registry+https://github.com/rust-lang/crates.io-index"
426
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
427
+ dependencies = [
428
+ "autocfg",
429
+ ]
430
+
431
+ [[package]]
432
+ name = "num_enum"
433
+ version = "0.7.3"
434
+ source = "registry+https://github.com/rust-lang/crates.io-index"
435
+ checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179"
436
+ dependencies = [
437
+ "num_enum_derive",
438
+ ]
439
+
440
+ [[package]]
441
+ name = "num_enum_derive"
442
+ version = "0.7.3"
443
+ source = "registry+https://github.com/rust-lang/crates.io-index"
444
+ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
445
+ dependencies = [
446
+ "proc-macro-crate",
447
+ "proc-macro2",
448
+ "quote",
449
+ "syn",
450
+ ]
451
+
452
+ [[package]]
453
+ name = "once_cell"
454
+ version = "1.19.0"
455
+ source = "registry+https://github.com/rust-lang/crates.io-index"
456
+ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
457
+
458
+ [[package]]
459
+ name = "proc-macro-crate"
460
+ version = "3.1.0"
461
+ source = "registry+https://github.com/rust-lang/crates.io-index"
462
+ checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
463
+ dependencies = [
464
+ "toml_edit",
465
+ ]
466
+
467
+ [[package]]
468
+ name = "proc-macro2"
469
+ version = "1.0.86"
470
+ source = "registry+https://github.com/rust-lang/crates.io-index"
471
+ checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
472
+ dependencies = [
473
+ "unicode-ident",
474
+ ]
475
+
476
+ [[package]]
477
+ name = "quick-xml"
478
+ version = "0.31.0"
479
+ source = "registry+https://github.com/rust-lang/crates.io-index"
480
+ checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
481
+ dependencies = [
482
+ "encoding_rs",
483
+ "memchr",
484
+ ]
485
+
486
+ [[package]]
487
+ name = "quote"
488
+ version = "1.0.36"
489
+ source = "registry+https://github.com/rust-lang/crates.io-index"
490
+ checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
491
+ dependencies = [
492
+ "proc-macro2",
493
+ ]
494
+
495
+ [[package]]
496
+ name = "rb-sys"
497
+ version = "0.9.98"
498
+ source = "registry+https://github.com/rust-lang/crates.io-index"
499
+ checksum = "8914b2e6af10bd50dd7aaac8c5146872d3924d6012929b4ff504e988f6badd24"
500
+ dependencies = [
501
+ "rb-sys-build",
502
+ ]
503
+
504
+ [[package]]
505
+ name = "rb-sys-build"
506
+ version = "0.9.98"
507
+ source = "registry+https://github.com/rust-lang/crates.io-index"
508
+ checksum = "12af68c9757d419b82d65a12b5db538990dfe9416049fea3f0ba4b9a8ca108cd"
509
+ dependencies = [
510
+ "bindgen",
511
+ "lazy_static",
512
+ "proc-macro2",
513
+ "quote",
514
+ "regex",
515
+ "shell-words",
516
+ "syn",
517
+ ]
518
+
519
+ [[package]]
520
+ name = "rb-sys-env"
521
+ version = "0.1.2"
522
+ source = "registry+https://github.com/rust-lang/crates.io-index"
523
+ checksum = "a35802679f07360454b418a5d1735c89716bde01d35b1560fc953c1415a0b3bb"
524
+
525
+ [[package]]
526
+ name = "regex"
527
+ version = "1.10.5"
528
+ source = "registry+https://github.com/rust-lang/crates.io-index"
529
+ checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
530
+ dependencies = [
531
+ "aho-corasick",
532
+ "memchr",
533
+ "regex-automata",
534
+ "regex-syntax",
535
+ ]
536
+
537
+ [[package]]
538
+ name = "regex-automata"
539
+ version = "0.4.7"
540
+ source = "registry+https://github.com/rust-lang/crates.io-index"
541
+ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
542
+ dependencies = [
543
+ "aho-corasick",
544
+ "memchr",
545
+ "regex-syntax",
546
+ ]
547
+
548
+ [[package]]
549
+ name = "regex-syntax"
550
+ version = "0.8.4"
551
+ source = "registry+https://github.com/rust-lang/crates.io-index"
552
+ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
553
+
554
+ [[package]]
555
+ name = "rustc-hash"
556
+ version = "1.1.0"
557
+ source = "registry+https://github.com/rust-lang/crates.io-index"
558
+ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
559
+
560
+ [[package]]
561
+ name = "ryu"
562
+ version = "1.0.18"
563
+ source = "registry+https://github.com/rust-lang/crates.io-index"
564
+ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
565
+
566
+ [[package]]
567
+ name = "seq-macro"
568
+ version = "0.3.5"
569
+ source = "registry+https://github.com/rust-lang/crates.io-index"
570
+ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4"
571
+
572
+ [[package]]
573
+ name = "serde"
574
+ version = "1.0.204"
575
+ source = "registry+https://github.com/rust-lang/crates.io-index"
576
+ checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
577
+ dependencies = [
578
+ "serde_derive",
579
+ ]
580
+
581
+ [[package]]
582
+ name = "serde_derive"
583
+ version = "1.0.204"
584
+ source = "registry+https://github.com/rust-lang/crates.io-index"
585
+ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
586
+ dependencies = [
587
+ "proc-macro2",
588
+ "quote",
589
+ "syn",
590
+ ]
591
+
592
+ [[package]]
593
+ name = "shell-words"
594
+ version = "1.1.0"
595
+ source = "registry+https://github.com/rust-lang/crates.io-index"
596
+ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
597
+
598
+ [[package]]
599
+ name = "shlex"
600
+ version = "1.3.0"
601
+ source = "registry+https://github.com/rust-lang/crates.io-index"
602
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
603
+
604
+ [[package]]
605
+ name = "syn"
606
+ version = "2.0.71"
607
+ source = "registry+https://github.com/rust-lang/crates.io-index"
608
+ checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
609
+ dependencies = [
610
+ "proc-macro2",
611
+ "quote",
612
+ "unicode-ident",
613
+ ]
614
+
615
+ [[package]]
616
+ name = "thiserror"
617
+ version = "1.0.63"
618
+ source = "registry+https://github.com/rust-lang/crates.io-index"
619
+ checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
620
+ dependencies = [
621
+ "thiserror-impl",
622
+ ]
623
+
624
+ [[package]]
625
+ name = "thiserror-impl"
626
+ version = "1.0.63"
627
+ source = "registry+https://github.com/rust-lang/crates.io-index"
628
+ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
629
+ dependencies = [
630
+ "proc-macro2",
631
+ "quote",
632
+ "syn",
633
+ ]
634
+
635
+ [[package]]
636
+ name = "toml_datetime"
637
+ version = "0.6.8"
638
+ source = "registry+https://github.com/rust-lang/crates.io-index"
639
+ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
640
+
641
+ [[package]]
642
+ name = "toml_edit"
643
+ version = "0.21.1"
644
+ source = "registry+https://github.com/rust-lang/crates.io-index"
645
+ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
646
+ dependencies = [
647
+ "indexmap",
648
+ "toml_datetime",
649
+ "winnow",
650
+ ]
651
+
652
+ [[package]]
653
+ name = "unicode-ident"
654
+ version = "1.0.12"
655
+ source = "registry+https://github.com/rust-lang/crates.io-index"
656
+ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
657
+
658
+ [[package]]
659
+ name = "wasm-bindgen"
660
+ version = "0.2.92"
661
+ source = "registry+https://github.com/rust-lang/crates.io-index"
662
+ checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
663
+ dependencies = [
664
+ "cfg-if",
665
+ "wasm-bindgen-macro",
666
+ ]
667
+
668
+ [[package]]
669
+ name = "wasm-bindgen-backend"
670
+ version = "0.2.92"
671
+ source = "registry+https://github.com/rust-lang/crates.io-index"
672
+ checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
673
+ dependencies = [
674
+ "bumpalo",
675
+ "log",
676
+ "once_cell",
677
+ "proc-macro2",
678
+ "quote",
679
+ "syn",
680
+ "wasm-bindgen-shared",
681
+ ]
682
+
683
+ [[package]]
684
+ name = "wasm-bindgen-macro"
685
+ version = "0.2.92"
686
+ source = "registry+https://github.com/rust-lang/crates.io-index"
687
+ checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
688
+ dependencies = [
689
+ "quote",
690
+ "wasm-bindgen-macro-support",
691
+ ]
692
+
693
+ [[package]]
694
+ name = "wasm-bindgen-macro-support"
695
+ version = "0.2.92"
696
+ source = "registry+https://github.com/rust-lang/crates.io-index"
697
+ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
698
+ dependencies = [
699
+ "proc-macro2",
700
+ "quote",
701
+ "syn",
702
+ "wasm-bindgen-backend",
703
+ "wasm-bindgen-shared",
704
+ ]
705
+
706
+ [[package]]
707
+ name = "wasm-bindgen-shared"
708
+ version = "0.2.92"
709
+ source = "registry+https://github.com/rust-lang/crates.io-index"
710
+ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
711
+
712
+ [[package]]
713
+ name = "windows-core"
714
+ version = "0.52.0"
715
+ source = "registry+https://github.com/rust-lang/crates.io-index"
716
+ checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
717
+ dependencies = [
718
+ "windows-targets",
719
+ ]
720
+
721
+ [[package]]
722
+ name = "windows-targets"
723
+ version = "0.52.6"
724
+ source = "registry+https://github.com/rust-lang/crates.io-index"
725
+ checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
726
+ dependencies = [
727
+ "windows_aarch64_gnullvm",
728
+ "windows_aarch64_msvc",
729
+ "windows_i686_gnu",
730
+ "windows_i686_gnullvm",
731
+ "windows_i686_msvc",
732
+ "windows_x86_64_gnu",
733
+ "windows_x86_64_gnullvm",
734
+ "windows_x86_64_msvc",
735
+ ]
736
+
737
+ [[package]]
738
+ name = "windows_aarch64_gnullvm"
739
+ version = "0.52.6"
740
+ source = "registry+https://github.com/rust-lang/crates.io-index"
741
+ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
742
+
743
+ [[package]]
744
+ name = "windows_aarch64_msvc"
745
+ version = "0.52.6"
746
+ source = "registry+https://github.com/rust-lang/crates.io-index"
747
+ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
748
+
749
+ [[package]]
750
+ name = "windows_i686_gnu"
751
+ version = "0.52.6"
752
+ source = "registry+https://github.com/rust-lang/crates.io-index"
753
+ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
754
+
755
+ [[package]]
756
+ name = "windows_i686_gnullvm"
757
+ version = "0.52.6"
758
+ source = "registry+https://github.com/rust-lang/crates.io-index"
759
+ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
760
+
761
+ [[package]]
762
+ name = "windows_i686_msvc"
763
+ version = "0.52.6"
764
+ source = "registry+https://github.com/rust-lang/crates.io-index"
765
+ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
766
+
767
+ [[package]]
768
+ name = "windows_x86_64_gnu"
769
+ version = "0.52.6"
770
+ source = "registry+https://github.com/rust-lang/crates.io-index"
771
+ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
772
+
773
+ [[package]]
774
+ name = "windows_x86_64_gnullvm"
775
+ version = "0.52.6"
776
+ source = "registry+https://github.com/rust-lang/crates.io-index"
777
+ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
778
+
779
+ [[package]]
780
+ name = "windows_x86_64_msvc"
781
+ version = "0.52.6"
782
+ source = "registry+https://github.com/rust-lang/crates.io-index"
783
+ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
784
+
785
+ [[package]]
786
+ name = "winnow"
787
+ version = "0.5.40"
788
+ source = "registry+https://github.com/rust-lang/crates.io-index"
789
+ checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
790
+ dependencies = [
791
+ "memchr",
792
+ ]
793
+
794
+ [[package]]
795
+ name = "zip"
796
+ version = "1.1.4"
797
+ source = "registry+https://github.com/rust-lang/crates.io-index"
798
+ checksum = "9cc23c04387f4da0374be4533ad1208cbb091d5c11d070dfef13676ad6497164"
799
+ dependencies = [
800
+ "arbitrary",
801
+ "crc32fast",
802
+ "crossbeam-utils",
803
+ "displaydoc",
804
+ "flate2",
805
+ "indexmap",
806
+ "num_enum",
807
+ "thiserror",
808
+ ]
data/Cargo.toml ADDED
@@ -0,0 +1,7 @@
1
+ # This Cargo.toml is here to let externals tools (IDEs, etc.) know that this is
2
+ # a Rust project. Your extensions dependencies should be added to the Cargo.toml
3
+ # in the ext/ directory.
4
+
5
+ [workspace]
6
+ members = ["./ext/csv_utils"]
7
+ resolver = "2"
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in csv_utils.gemspec
6
+ gemspec
7
+
8
+ group :development do
9
+ gem 'rake', '~> 13.0'
10
+ gem 'rake-compiler'
11
+ gem 'rb_sys', '~> 0.9.98'
12
+ gem 'rspec', '~> 3.0'
13
+ gem 'rubocop', '~> 1.21'
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ patchwork_csv_utils (0.1.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.2)
10
+ diff-lcs (1.5.1)
11
+ json (2.7.2)
12
+ language_server-protocol (3.17.0.3)
13
+ parallel (1.25.1)
14
+ parser (3.3.4.0)
15
+ ast (~> 2.4.1)
16
+ racc
17
+ racc (1.8.0)
18
+ rainbow (3.1.1)
19
+ rake (13.2.1)
20
+ rake-compiler (1.2.7)
21
+ rake
22
+ rb_sys (0.9.98)
23
+ regexp_parser (2.9.2)
24
+ rexml (3.3.2)
25
+ strscan
26
+ rspec (3.13.0)
27
+ rspec-core (~> 3.13.0)
28
+ rspec-expectations (~> 3.13.0)
29
+ rspec-mocks (~> 3.13.0)
30
+ rspec-core (3.13.0)
31
+ rspec-support (~> 3.13.0)
32
+ rspec-expectations (3.13.1)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.13.0)
35
+ rspec-mocks (3.13.1)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.13.0)
38
+ rspec-support (3.13.1)
39
+ rubocop (1.65.0)
40
+ json (~> 2.3)
41
+ language_server-protocol (>= 3.17.0)
42
+ parallel (~> 1.10)
43
+ parser (>= 3.3.0.2)
44
+ rainbow (>= 2.2.2, < 4.0)
45
+ regexp_parser (>= 2.4, < 3.0)
46
+ rexml (>= 3.2.5, < 4.0)
47
+ rubocop-ast (>= 1.31.1, < 2.0)
48
+ ruby-progressbar (~> 1.7)
49
+ unicode-display_width (>= 2.4.0, < 3.0)
50
+ rubocop-ast (1.31.3)
51
+ parser (>= 3.3.1.0)
52
+ ruby-progressbar (1.13.0)
53
+ strscan (3.1.0)
54
+ unicode-display_width (2.5.0)
55
+
56
+ PLATFORMS
57
+ arm64-darwin-22
58
+ arm64-darwin-23
59
+ x86_64-linux
60
+
61
+ DEPENDENCIES
62
+ patchwork_csv_utils!
63
+ rake (~> 13.0)
64
+ rake-compiler
65
+ rb_sys (~> 0.9.98)
66
+ rspec (~> 3.0)
67
+ rubocop (~> 1.21)
68
+
69
+ BUNDLED WITH
70
+ 2.4.4
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # CsvUtils
2
+
3
+ * dedup: Given 2 CSV files, this gem will create a third CSV file that contains rows from the first CSV file that are not present in the second CSV file.
4
+ * xls to csv: Given an XLS file, this gem will create a CSV file with the specified name.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ gem install patchwork_csv_utils
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ```irb
15
+ require 'csv_utils'
16
+ CsvUtils.dedup('file1.csv', 'file2.csv', 'output.csv')
17
+ CsvUtils.to_csv('file1.xls', 'output_file1.csv', 'sheet_name')
18
+ ```
19
+
20
+ ## Release
21
+
22
+ * to release a new version, update the version number in `lib/patchwork_csv_utils/version.rb`
23
+ * push the changes to github and then create a tag with the version number
24
+
25
+ ```bash
26
+ git tag -a v0.1.0 -m "v0.1.0"
27
+ git push origin --tags
28
+ ```
29
+
30
+ ## Contributing
31
+
32
+ Bug reports and pull requests are welcome on GitHub at http://github.com/patchworkhealth/csv_utils.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ require 'rb_sys/extensiontask'
13
+
14
+ task build: :compile
15
+
16
+ spec = Bundler.load_gemspec('patchwork_csv_utils.gemspec')
17
+
18
+ Rake::ExtensionTask.new('csv_utils', spec) do |c|
19
+ c.lib_dir = 'lib/csv_utils'
20
+ c.cross_compile = true
21
+ c.cross_platform = %w[
22
+ aarch64-linux
23
+ arm64-darwin
24
+ x64-mingw-ucrt
25
+ x64-mingw32
26
+ x86_64-darwin
27
+ x86_64-linux
28
+ x86_64-linux-musl
29
+ ]
30
+ end
31
+
32
+ RbSys::ExtensionTask.new('csv_utils') do |ext|
33
+ ext.lib_dir = 'lib/csv_utils'
34
+ end
35
+
36
+ task default: %i[compile spec rubocop]
@@ -0,0 +1,15 @@
1
+ [package]
2
+ name = "csv_utils"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ authors = ["kingsley.hendrickse <kingsley.hendrickse@patchwork.health>"]
6
+ publish = false
7
+
8
+ [lib]
9
+ crate-type = ["cdylib"]
10
+
11
+ [dependencies]
12
+ magnus = { version = "0.7.1" }
13
+ csv = "1.3.0"
14
+ calamine = { version = "0.25.0", features = ["dates"] }
15
+ chrono = "0.4.38"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+ require 'rb_sys/mkmf'
5
+
6
+ create_rust_makefile('csv_utils/csv_utils')
@@ -0,0 +1,13 @@
1
+ use magnus::{define_module, function, prelude::*};
2
+ use crate::utils::dedup::dedup;
3
+ use crate::utils::xls::to_csv;
4
+
5
+ pub mod utils;
6
+
7
+ #[magnus::init]
8
+ fn init() -> Result<(), magnus::Error> {
9
+ let module = define_module("CsvUtils")?;
10
+ module.define_singleton_method("dedup", function!(dedup, 3))?;
11
+ module.define_singleton_method("to_csv", function!(to_csv, 3))?;
12
+ Ok(())
13
+ }
@@ -0,0 +1,53 @@
1
+ use std::fs::File;
2
+
3
+ use csv::{StringRecord, Writer};
4
+ use magnus::Ruby;
5
+
6
+ use crate::utils::{FileExtension, magnus_err};
7
+
8
+ pub fn dedup(ruby: &Ruby, previous_csv_path: String, new_csv_path: String, target_path: String) -> magnus::error::Result<()> {
9
+ if !previous_csv_path.has_extension(&["csv"]) {
10
+ return Err(magnus::Error::new(ruby.exception_standard_error(), "previous_csv_path must be a csv file".to_string()));
11
+ }
12
+ if !new_csv_path.has_extension(&["csv"]) {
13
+ return Err(magnus::Error::new(ruby.exception_standard_error(), "new_csv_path must be a csv file".to_string()));
14
+ }
15
+
16
+ let csv1 = File::open(previous_csv_path).map_err(|e| magnus_err(ruby, e, "previous_csv_path"))?;
17
+ let csv2 = File::open(new_csv_path).map_err(|e| magnus_err(ruby, e, "new_csv_path"))?;
18
+
19
+ let mut previous_csv: csv::Reader<File> = csv::Reader::from_reader(csv1);
20
+ let mut new_csv: csv::Reader<File> = csv::Reader::from_reader(csv2);
21
+
22
+ let mut wtr = Writer::from_path(target_path).map_err(|e| magnus_err(ruby, e, "target_path"))?;
23
+
24
+ let previous_headers = previous_csv.headers().map_err(|e| magnus_err(ruby, e, "previous_csv_path headers"))?;
25
+ let new_headers = new_csv.headers().map_err(|e| magnus_err(ruby, e, "new_csv_path headers"))?;
26
+
27
+ if previous_headers != new_headers {
28
+ return Err(magnus::Error::new(ruby.exception_standard_error(), "headers of both csv files must be the same".to_string()));
29
+ }
30
+
31
+ wtr.write_byte_record(previous_headers.as_byte_record()).unwrap();
32
+
33
+ let mut previous_records = vec![];
34
+ for previous_record in previous_csv.records() {
35
+ let previous_record = previous_record.map_err(|e| magnus_err(ruby, e, "previous_record"))?;
36
+ let previous_record = previous_record.into_iter().map(|r| r.trim_end()).collect::<StringRecord>();
37
+ previous_records.push(previous_record)
38
+ }
39
+
40
+ for new_record in new_csv.records() {
41
+ let new_record = new_record.map_err(|e| magnus_err(ruby, e, "new_record"))?;
42
+ let new_record = new_record.into_iter().map(|r| r.trim_end()).collect::<StringRecord>();
43
+ if !previous_records.contains(&new_record) {
44
+ wtr.write_byte_record(new_record.as_byte_record()).unwrap();
45
+ }
46
+ }
47
+
48
+ wtr.flush().unwrap();
49
+
50
+ Ok(())
51
+ }
52
+
53
+
@@ -0,0 +1,27 @@
1
+ use std::error::Error;
2
+ use std::ffi::OsStr;
3
+ use std::path::Path;
4
+ use magnus::Ruby;
5
+
6
+ pub mod dedup;
7
+ pub mod xls;
8
+
9
+ fn magnus_err<E: Error>(ruby: &Ruby, e: E, msg: &str) -> magnus::Error {
10
+ magnus::Error::new(ruby.exception_standard_error(), format!("{}: {}", msg, e.to_string()))
11
+ }
12
+
13
+ pub trait FileExtension {
14
+ fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool;
15
+ }
16
+
17
+ impl<P: AsRef<Path>> FileExtension for P {
18
+ fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool {
19
+ if let Some(ref extension) = self.as_ref().extension().and_then(OsStr::to_str) {
20
+ return extensions
21
+ .iter()
22
+ .any(|x| x.as_ref().eq_ignore_ascii_case(extension));
23
+ }
24
+
25
+ false
26
+ }
27
+ }
@@ -0,0 +1,84 @@
1
+ use std::collections::HashMap;
2
+ use std::fs::File;
3
+ use std::io::{BufWriter, Write};
4
+
5
+ use calamine::{Data, open_workbook, Range, Reader, Xls};
6
+ use chrono::{NaiveDateTime, Utc};
7
+ use magnus::Ruby;
8
+
9
+ use crate::utils::{FileExtension, magnus_err};
10
+
11
+ pub fn to_csv(ruby: &Ruby, xls_path: String, target_path: String, sheet_name: String) -> magnus::error::Result<()> {
12
+ if !xls_path.has_extension(&["xls"]) {
13
+ return Err(magnus::Error::new(ruby.exception_standard_error(), "xls_path must be an xls file".to_string()));
14
+ }
15
+
16
+ let mut workbook: Xls<_> = open_workbook(xls_path.clone()).map_err(|e| magnus_err(ruby, e, format!("could not open xls: {}", xls_path).as_str()))?;
17
+ let range = workbook.worksheet_range(sheet_name.as_str()).map_err(|e| magnus_err(ruby, e, "Error"))?;
18
+
19
+ let headers = range.headers().ok_or(magnus::Error::new(ruby.exception_standard_error(), "no headers found in xls".to_string()))?;
20
+ let header_map: HashMap<String, usize> = headers.iter().enumerate().map(|(i, h)| (h.to_string(), i)).collect();
21
+ let csv_out_file = File::create(target_path.clone()).map_err(|e| magnus_err(ruby, e, format!("could not create csv file: {}", target_path).as_str()))?;
22
+ let mut dest = BufWriter::new(csv_out_file);
23
+
24
+ write_csv(ruby, &mut dest, &range, header_map)
25
+ }
26
+
27
+ fn write_csv<W: Write>(ruby: &Ruby, dest: &mut W, range: &Range<Data>, header_map: HashMap<String, usize>) -> magnus::error::Result<()> {
28
+ let n = range.get_size().1 - 1;
29
+ for (ri, r) in range.rows().enumerate() {
30
+ let mut date_value = Utc::now().naive_utc();
31
+ for (i, c) in r.iter().enumerate() {
32
+ let date = header_map.get("Date").ok_or(missing_header(ruby, "Date"))?;
33
+ let start = header_map.get("Start").ok_or(missing_header(ruby, "Start"))?;
34
+ let end = header_map.get("End").ok_or(missing_header(ruby, "End"))?;
35
+ let actual_start = header_map.get("Actual Start").ok_or(missing_header(ruby, "Actual Start"))?;
36
+ let actual_end = header_map.get("Actual End").ok_or(missing_header(ruby, "Actual End"))?;
37
+
38
+ match *c {
39
+ Data::Empty => Ok(()),
40
+ Data::String(ref s) | Data::DateTimeIso(ref s) | Data::DurationIso(ref s) => {
41
+ handle_commas(dest, s)
42
+ }
43
+ Data::Float(ref f) => write!(dest, "{}", f),
44
+ Data::DateTime(ref d) => {
45
+ let mut current = d.as_datetime().unwrap_or_default();
46
+ if i == *date {
47
+ date_value = current;
48
+ } else if i == *start || i == *end || i == *actual_start || i == *actual_end {
49
+ current = transform_time_to_datetime(date_value, current);
50
+ }
51
+ write!(dest, "{}", current)
52
+ }
53
+ Data::Int(ref i) => write!(dest, "{}", i),
54
+ Data::Error(ref e) => write!(dest, "{:?}", e),
55
+ Data::Bool(ref b) => write!(dest, "{}", b),
56
+ }.map_err(|e| magnus_err(ruby, e, format!("error writing xls row: {}, column: {}", ri, i).as_str()))?;
57
+ if i != n {
58
+ write!(dest, ",").map_err(|e| magnus_err(ruby, e, format!("error writing csv comma for row: {}, column: {}", ri, i).as_str()))?;
59
+ }
60
+ }
61
+ write!(dest, "\r\n").map_err(|e| magnus_err(ruby, e, format!("error writing end of line for row: {}", ri).as_str()))?;
62
+ }
63
+ Ok(())
64
+ }
65
+
66
+ fn missing_header(ruby: &Ruby, header: &str) -> magnus::Error {
67
+ magnus::Error::new(ruby.exception_standard_error(), format!("Missing '{}' header in xls", header))
68
+ }
69
+
70
+ fn transform_time_to_datetime(t1: NaiveDateTime, t2: NaiveDateTime) -> NaiveDateTime {
71
+ NaiveDateTime::new(t1.date(), t2.time())
72
+ }
73
+
74
+ fn handle_commas<W: Write>(dest: &mut W, s: &str) -> std::io::Result<()> {
75
+ if s.contains(",") {
76
+ write!(dest, "{:?}", remove_new_lines(s.trim_end()))
77
+ } else {
78
+ write!(dest, "{}", remove_new_lines(s.trim_end()))
79
+ }
80
+ }
81
+
82
+ fn remove_new_lines(s: &str) -> String {
83
+ s.replace("\n", " ").replace("\r", " ")
84
+ }
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CsvUtils
4
+ VERSION = '0.1.1'
5
+ end
data/lib/csv_utils.rb ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # load native extension
4
+ begin
5
+ ruby_version = /(\d+\.\d+)/.match(RUBY_VERSION)
6
+ require_relative "csv_utils/#{ruby_version}/csv_utils"
7
+ rescue LoadError
8
+ require_relative 'csv_utils/csv_utils'
9
+ end
10
+
11
+ require_relative 'csv_utils/version'
12
+
13
+ module CsvUtils
14
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: patchwork_csv_utils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: x86_64-darwin
6
+ authors:
7
+ - kingsley.hendrickse
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-07-31 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Deduplication of CSV files and XLS to CSV conversion.
14
+ email:
15
+ - kingsley.hendrickse@patchwork.health
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - ".rubocop.yml"
22
+ - Cargo.lock
23
+ - Cargo.toml
24
+ - Gemfile
25
+ - Gemfile.lock
26
+ - README.md
27
+ - Rakefile
28
+ - ext/csv_utils/Cargo.toml
29
+ - ext/csv_utils/extconf.rb
30
+ - ext/csv_utils/src/lib.rs
31
+ - ext/csv_utils/src/utils/dedup.rs
32
+ - ext/csv_utils/src/utils/mod.rs
33
+ - ext/csv_utils/src/utils/xls.rs
34
+ - lib/csv_utils.rb
35
+ - lib/csv_utils/2.7/csv_utils.bundle
36
+ - lib/csv_utils/3.0/csv_utils.bundle
37
+ - lib/csv_utils/3.1/csv_utils.bundle
38
+ - lib/csv_utils/3.2/csv_utils.bundle
39
+ - lib/csv_utils/version.rb
40
+ homepage: http://github.com/patchworkhealth/csv_utils
41
+ licenses: []
42
+ metadata:
43
+ homepage_uri: http://github.com/patchworkhealth/csv_utils
44
+ source_code_uri: http://github.com/patchworkhealth/csv_utils
45
+ rubygems_mfa_required: 'false'
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '2.7'
55
+ - - "<"
56
+ - !ruby/object:Gem::Version
57
+ version: 3.3.dev
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.4.4
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Fast CSV utils
68
+ test_files: []