< Summary

Information
Class: ArturRios.Data.Export.Exporters.CsvExporter<T>
Assembly: ArturRios.Data.Export
File(s): D:\Repositories\dotnet-data\src\ArturRios.Data.Export\Exporters\CsvExporter.cs
Line coverage
100%
Covered lines: 21
Uncovered lines: 0
Coverable lines: 21
Total lines: 38
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage
100%
Covered methods: 3
Fully covered methods: 2
Total methods: 3
Method coverage: 100%
Full method coverage: 66.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
WriteCoreAsync()100%44100%
Escape(...)100%88100%

File(s)

D:\Repositories\dotnet-data\src\ArturRios.Data.Export\Exporters\CsvExporter.cs

#LineLine coverage
 1using ArturRios.Data.Export.Abstractions;
 2using ArturRios.Data.Export.Configuration;
 3
 4namespace ArturRios.Data.Export.Exporters;
 5
 6/// <summary>Writes records as RFC 4180 CSV using the shared column map.</summary>
 7/// <typeparam name="T">The record type.</typeparam>
 8/// <param name="options">CSV options.</param>
 89public class CsvExporter<T>(CsvOptions options) : ExporterBase<T> where T : class
 10{
 11    /// <inheritdoc />
 12    protected override async Task WriteCoreAsync(IEnumerable<T> data, Stream destination, CancellationToken ct)
 613    {
 614        var columns = ColumnMap.For<T>();
 615        await using var writer = new StreamWriter(destination, options.Encoding, leaveOpen: true);
 16
 617        if (options.IncludeHeader)
 518        {
 519            await writer.WriteLineAsync(string.Join(options.Delimiter,
 2020                columns.Select(c => Escape(c.Header, options.Delimiter))));
 521        }
 22
 2823        foreach (var item in data)
 524        {
 525            ct.ThrowIfCancellationRequested();
 526            await writer.WriteLineAsync(string.Join(options.Delimiter,
 2027                columns.Select(c => Escape(ValueRenderer.Render(c.Getter(item)), options.Delimiter))));
 528        }
 29
 630        await writer.FlushAsync(ct);
 631    }
 32
 33    private static string Escape(string field, char delimiter)
 3034    {
 3035        var mustQuote = field.Contains(delimiter) || field.Contains('"') || field.Contains('\n') || field.Contains('\r')
 3036        return mustQuote ? $"\"{field.Replace("\"", "\"\"")}\"" : field;
 3037    }
 38}