Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 8359e12

Browse files
refactor: extract CSV reader helper methods for better maintainability
1 parent b368707 commit 8359e12

1 file changed

Lines changed: 29 additions & 22 deletions

File tree

  • src/ServiceLayer.Mesh/FileTypes/NbssAppointmentEvents

src/ServiceLayer.Mesh/FileTypes/NbssAppointmentEvents/FileParser.cs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,9 @@ public ParsedFile Parse(Stream stream)
2626
throw new ArgumentNullException(nameof(stream), "Stream cannot be null");
2727
}
2828

29-
using var reader = new StreamReader(stream, Encoding.UTF8, true, 1024, leaveOpen: true);
30-
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
31-
{
32-
Delimiter = "|",
33-
Quote = '"',
34-
Escape = '\\',
35-
HasHeaderRecord = false,
36-
Mode = CsvMode.RFC4180,
37-
BadDataFound = null
38-
};
29+
using var reader = CreateStreamReader(stream);
30+
using var csv = CreateCsvReader(reader);
3931

40-
using var csv = new CsvReader(reader, config);
41-
csv.Context.RegisterClassMap<FileHeaderRecordMap>();
42-
csv.Context.RegisterClassMap<FileTrailerRecordMap>();
4332
var rowNumber = 0;
4433
var fields = new List<string>();
4534

@@ -50,7 +39,7 @@ public ParsedFile Parse(Stream stream)
5039
switch (recordIdentifier)
5140
{
5241
case HeaderIdentifier:
53-
result.FileHeader = csv.GetRecord<FileHeaderRecord>();
42+
result.FileHeader = ParseHeader(csv);
5443
break;
5544

5645
case FieldsIdentifier:
@@ -59,16 +48,11 @@ public ParsedFile Parse(Stream stream)
5948

6049
case DataIdentifier:
6150
rowNumber++;
62-
if (fields.Count == 0)
63-
{
64-
throw new InvalidOperationException("Field headers (NBSSAPPT_FLDS) must appear before data records.");
65-
}
66-
6751
result.DataRecords.Add(ParseDataRecord(csv, fields, rowNumber));
6852
break;
6953

7054
case TrailerIdentifier:
71-
result.FileTrailer = csv.GetRecord<FileTrailerRecord>();
55+
result.FileTrailer = ParseTrailer(csv);
7256
break;
7357

7458
default:
@@ -87,13 +71,36 @@ private static List<string> ParseFields(CsvReader csv)
8771
.ToList()!;
8872
}
8973

90-
private static string? GetFieldValue(CsvReader csv, int index)
74+
private static string? GetFieldValue(CsvReader csv, int index) => index < csv.Parser.Count ? csv.GetField(index)?.Trim('"') : null;
75+
private static StreamReader CreateStreamReader(Stream stream) => new(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true);
76+
private static FileHeaderRecord ParseHeader(CsvReader csv) => csv.GetRecord<FileHeaderRecord>();
77+
private static FileTrailerRecord ParseTrailer(CsvReader csv) => csv.GetRecord<FileTrailerRecord>();
78+
private static CsvReader CreateCsvReader(StreamReader reader)
9179
{
92-
return index < csv.Parser.Count ? csv.GetField(index)?.Trim('"') : null;
80+
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
81+
{
82+
Delimiter = "|",
83+
Quote = '"',
84+
Escape = '\\',
85+
HasHeaderRecord = false,
86+
Mode = CsvMode.RFC4180,
87+
BadDataFound = null
88+
};
89+
90+
var csv = new CsvReader(reader, config);
91+
csv.Context.RegisterClassMap<FileHeaderRecordMap>();
92+
csv.Context.RegisterClassMap<FileTrailerRecordMap>();
93+
94+
return csv;
9395
}
9496

9597
private static FileDataRecord ParseDataRecord(CsvReader csv, List<string> columnHeadings, int rowNumber)
9698
{
99+
if (columnHeadings.Count == 0)
100+
{
101+
throw new InvalidOperationException("Field headers (NBSSAPPT_FLDS) must appear before data records.");
102+
}
103+
97104
const int dataFieldStartIndex = 1;
98105

99106
var record = new FileDataRecord { RowNumber = rowNumber };

0 commit comments

Comments
 (0)