Skip to content

Commit e5f81b4

Browse files
committed
Fix: Code Cleanup
**Twitch Redeems** - brought to you by `Ydouwantjustasking` with : "Let's do update on today's stream -🦆"
1 parent 83f3fdb commit e5f81b4

16 files changed

+324
-290
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ dotnet_naming_symbols.private_instance_fields_symbols.resharper_applicable_kinds
7171
dotnet_naming_symbols.private_instance_fields_symbols.resharper_required_modifiers = instance
7272
dotnet_naming_symbols.private_instance_fields_symbols_1.applicable_accessibilities = private
7373
dotnet_naming_symbols.private_instance_fields_symbols_1.applicable_kinds = field
74-
dotnet_naming_symbols.private_instance_fields_symbols_1.resharper_applicable_kinds = field,readonly_field
74+
dotnet_naming_symbols.private_instance_fields_symbols_1.resharper_applicable_kinds = field, readonly_field
7575
dotnet_naming_symbols.private_instance_fields_symbols_1.resharper_required_modifiers = instance
7676
dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
7777
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field

src/CodeOfChaos.Parsers.Csv/CodeOfChaos.Parsers.Csv.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
</PropertyGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="CodeOfChaos.Extensions" Version="0.27.1" />
26+
<PackageReference Include="CodeOfChaos.Extensions" Version="0.27.1"/>
2727
</ItemGroup>
2828

2929
<ItemGroup>
30-
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
31-
<None Include="README.md" Pack="true" PackagePath="" />
32-
<None Include="../../assets/icon.png" Pack="true" PackagePath="" />
30+
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false"/>
31+
<None Include="README.md" Pack="true" PackagePath="" Visible="false"/>
32+
<None Include="../../assets/icon.png" Pack="true" PackagePath="" Visible="false"/>
3333
</ItemGroup>
3434

3535
</Project>

src/CodeOfChaos.Parsers.Csv/Contracts/ICsvReader.cs

-13
This file was deleted.

src/CodeOfChaos.Parsers.Csv/Contracts/ICsvWriter.cs

-13
This file was deleted.

src/CodeOfChaos.Parsers.Csv/CsvParser.cs

+58-57
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ namespace CodeOfChaos.Parsers.Csv;
1616
/// Provides functionality to parse CSV files into various collection types.
1717
/// </summary>
1818
public class CsvParser(CsvParserConfig config) : ICsvParser {
19-
protected readonly ConcurrentDictionary<Type, PropertyInfo[]> PropertyCache = new();
2019
protected readonly ConcurrentDictionary<Type, string[]> HeaderCache = new();
21-
22-
// -----------------------------------------------------------------------------------------------------------------
23-
// Constructors
24-
// -----------------------------------------------------------------------------------------------------------------
20+
protected readonly ConcurrentDictionary<Type, PropertyInfo[]> PropertyCache = new();
21+
/// <inheritdoc />
22+
public void ClearCaches() {
23+
PropertyCache.Clear();
24+
HeaderCache.Clear();
25+
}
2526
/// <summary>
2627
/// Creates an instance of <see cref="CsvParser" /> using the specified configuration action.
2728
/// </summary>
@@ -38,15 +39,50 @@ public static CsvParser FromConfig(Action<CsvParserConfig> configAction) {
3839
configAction(config);
3940
return new CsvParser(config);
4041
}
41-
4242
/// <summary>
43-
/// Creates an instance of <see cref="CsvParser" /> using the default configuration.
43+
/// Creates an instance of <see cref="CsvParser" /> using the default configuration.
4444
/// </summary>
4545
/// <returns>
46-
/// A new instance of <see cref="CsvParser" /> initialized with the default settings, ready
47-
/// to parse CSV data.
46+
/// A new instance of <see cref="CsvParser" /> initialized with the default settings, ready
47+
/// to parse CSV data.
4848
/// </returns>
4949
public static CsvParser FromDefaultConfig() => new(new CsvParserConfig());
50+
protected PropertyInfo[] GetCsvProperties<T>() {
51+
Type type = typeof(T);
52+
if (PropertyCache.TryGetValue(type, out PropertyInfo[]? propertyInfos)) return propertyInfos;
53+
54+
PropertyInfo[] propertyInfosArray = type.GetProperties().ToArray();
55+
PropertyCache[type] = propertyInfosArray;
56+
return propertyInfosArray;
57+
}
58+
protected string[] GetCsvHeaders<T>() {
59+
Type type = typeof(T);
60+
if (HeaderCache.TryGetValue(type, out string[]? headers)) return headers;
61+
62+
string[] headersArray = GetCsvProperties<T>()
63+
.Select(p => {
64+
if (p.GetCustomAttribute<CsvColumnAttribute>() is not {} attribute)
65+
return config.UseLowerCaseHeaders ? p.Name.ToLowerInvariant() : p.Name;
66+
67+
return config.UseLowerCaseHeaders
68+
? attribute.NameLowerInvariant
69+
: attribute.Name;
70+
})
71+
.ToArray();
72+
73+
HeaderCache[type] = headersArray;
74+
return headersArray;
75+
}
76+
protected IEnumerable<string> GetCsvValues<T>(T? obj) {
77+
if (obj is null) return [];
78+
79+
return GetCsvProperties<T>()
80+
.Select(p => p.GetValue(obj)?.ToString() ?? string.Empty);
81+
}
82+
83+
// -----------------------------------------------------------------------------------------------------------------
84+
// Constructors
85+
// -----------------------------------------------------------------------------------------------------------------
5086

5187
// -----------------------------------------------------------------------------------------------------------------
5288
// Input Methods
@@ -173,6 +209,7 @@ public async ValueTask<List<T>> ToListAsync<T>(TextReader reader, CancellationTo
173209
await foreach (Dictionary<string, string?> item in FromTextReaderToDictionaryAsync(reader, ct)) {
174210
results.Add(item);
175211
}
212+
176213
return results.ToArray();
177214
}
178215

@@ -184,7 +221,7 @@ public async ValueTask<List<T>> ToListAsync<T>(TextReader reader, CancellationTo
184221
await foreach (Dictionary<string, string?> item in FromTextReaderToDictionaryAsync(reader, ct)) {
185222
results.Add(item);
186223
}
187-
224+
188225
results.TrimExcess();
189226
return results.ToArray();
190227
}
@@ -205,7 +242,7 @@ public async ValueTask<List<T>> ToListAsync<T>(TextReader reader, CancellationTo
205242
await foreach (Dictionary<string, string?> item in FromTextReaderToDictionaryAsync(reader, ct)) {
206243
results.Add(item);
207244
}
208-
245+
209246
results.TrimExcess();
210247
return results;
211248
}
@@ -217,7 +254,7 @@ public async ValueTask<List<T>> ToListAsync<T>(TextReader reader, CancellationTo
217254
await foreach (Dictionary<string, string?> item in FromTextReaderToDictionaryAsync(reader, ct)) {
218255
results.Add(item);
219256
}
220-
257+
221258
results.TrimExcess();
222259
return results;
223260
}
@@ -355,14 +392,14 @@ private async IAsyncEnumerable<T> FromTextReaderAsync<T>(TextReader reader, [Enu
355392
}
356393

357394
batch.Clear();
358-
ct.ThrowIfCancellationRequested(); // After a batch is done, check if the cancellation token was requested
395+
ct.ThrowIfCancellationRequested();// After a batch is done, check if the cancellation token was requested
359396
if (line == null) break;
360397
}
361398
}
362399

363400
private void SetPropertyFromCsvColumn<T>(T? value, string[] headerColumns, string[] values) where T : class, new() {
364401
if (value is null) return;
365-
402+
366403
foreach (PropertyInfo prop in GetCsvProperties<T>()) {
367404
int columnIndex = Attribute.GetCustomAttribute(prop, typeof(CsvColumnAttribute)) is CsvColumnAttribute attribute
368405
? Array.IndexOf(headerColumns, attribute.Name)
@@ -401,6 +438,7 @@ private async IAsyncEnumerable<T> FromTextReaderAsync<T>(TextReader reader, [Enu
401438
string value = values[j];
402439
dict[headerColumns[j]] = value.IsNotNullOrEmpty() ? value : null;
403440
}
441+
404442
batch.Add(dict);
405443
}
406444

@@ -431,6 +469,7 @@ private async IAsyncEnumerable<T> FromTextReaderAsync<T>(TextReader reader, [Enu
431469
string value = values[j];
432470
dict[headerColumns[j]] = value.IsNotNullOrEmpty() ? value : null;
433471
}
472+
434473
batch.Add(dict);
435474
}
436475

@@ -439,12 +478,11 @@ private async IAsyncEnumerable<T> FromTextReaderAsync<T>(TextReader reader, [Enu
439478
}
440479

441480
batch.Clear();
442-
ct.ThrowIfCancellationRequested(); // After a batch is done, check if the cancellation token was requested
481+
ct.ThrowIfCancellationRequested();// After a batch is done, check if the cancellation token was requested
443482
if (line == null) break;
444483
}
445484
}
446485
#endregion
447-
448486
#region Generic Type Writer
449487
private void FromDataToTextWriter<T>(TextWriter writer, IEnumerable<T> data) {
450488
// Write header row
@@ -457,6 +495,7 @@ private void FromDataToTextWriter<T>(TextWriter writer, IEnumerable<T> data) {
457495

458496
writer.Write(Environment.NewLine);
459497
}
498+
460499
// Write data rows
461500
foreach (T? obj in data) {
462501
string[] values = GetCsvValues(obj).ToArray();
@@ -481,6 +520,7 @@ private async Task FromDataToTextWriterAsync<T>(TextWriter writer, IEnumerable<T
481520
await writer.WriteAsync(Environment.NewLine);
482521
ct.ThrowIfCancellationRequested();
483522
}
523+
484524
// Write data rows
485525
foreach (T? obj in data) {
486526
string[] values = GetCsvValues(obj).ToArray();
@@ -522,15 +562,15 @@ private async Task FromDictionaryToTextWriterAsync(TextWriter writer, IEnumerabl
522562
IDictionary<string, string?> firstDictionary = records.First();
523563
IEnumerable<string> headers = firstDictionary.Keys;
524564
await writer.WriteLineAsync(string.Join(config.ColumnSplit, headers));
525-
565+
526566
ct.ThrowIfCancellationRequested();
527567
}
528568

529569
// Write data rows
530570
foreach (IDictionary<string, string?> dictionary in records) {
531571
IEnumerable<string> values = dictionary.Values.Select(value => value?.ToString() ?? string.Empty);
532572
await writer.WriteLineAsync(string.Join(config.ColumnSplit, values));
533-
573+
534574
ct.ThrowIfCancellationRequested();
535575
}
536576
}
@@ -539,43 +579,4 @@ private async Task FromDictionaryToTextWriterAsync(TextWriter writer, IEnumerabl
539579
// -----------------------------------------------------------------------------------------------------------------
540580
// Methods
541581
// -----------------------------------------------------------------------------------------------------------------
542-
/// <inheritdoc />
543-
public void ClearCaches() {
544-
PropertyCache.Clear();
545-
HeaderCache.Clear();
546-
}
547-
548-
protected PropertyInfo[] GetCsvProperties<T>() {
549-
Type type = typeof(T);
550-
if (PropertyCache.TryGetValue(type, out PropertyInfo[]? propertyInfos)) return propertyInfos;
551-
PropertyInfo[] propertyInfosArray = type.GetProperties().ToArray();
552-
PropertyCache[type] = propertyInfosArray;
553-
return propertyInfosArray;
554-
}
555-
556-
protected string[] GetCsvHeaders<T>() {
557-
Type type = typeof(T);
558-
if (HeaderCache.TryGetValue(type, out string[]? headers)) return headers;
559-
560-
string[] headersArray = GetCsvProperties<T>()
561-
.Select(p => {
562-
if (p.GetCustomAttribute<CsvColumnAttribute>() is not {} attribute)
563-
return config.UseLowerCaseHeaders ? p.Name.ToLowerInvariant() : p.Name;
564-
565-
return config.UseLowerCaseHeaders
566-
? attribute.NameLowerInvariant
567-
: attribute.Name;
568-
})
569-
.ToArray();
570-
571-
HeaderCache[type] = headersArray;
572-
return headersArray;
573-
}
574-
575-
protected IEnumerable<string> GetCsvValues<T>(T? obj) {
576-
if (obj is null) return [];
577-
578-
return GetCsvProperties<T>()
579-
.Select(p => p.GetValue(obj)?.ToString() ?? string.Empty);
580-
}
581582
}

src/CodeOfChaos.Parsers.Csv/CsvParserConfig.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ namespace CodeOfChaos.Parsers.Csv;
66
// Code
77
// ---------------------------------------------------------------------------------------------------------------------
88
public class CsvParserConfig {
9+
public int BatchSize = 100;
910
public string ColumnSplit = ",";
1011
public bool IncludeHeader = true;
12+
public int InitialCapacity = 1000;
1113
public bool LogErrors = false;
1214
public bool UseLowerCaseHeaders = false;
13-
public int BatchSize = 100;
14-
public int InitialCapacity = 1000;
1515
}

0 commit comments

Comments
 (0)