Source Generator
Foreword
For 99% of applications, reflection works perfectly and is straightforward to set up with minimal configuration. However, reflection and compiled expressions are incompatible with AOT compilation, trimming, and platforms without JIT.
The performance differences between reflection and source generation in FlameCsv are extremely small, and you should pick the approach that best fits your application's needs.
The source-generated enum converter however is significantly faster than Enum.TryParse and TryFormat,
especially when reading UTF-8 (bytes). For more details, see the benchmarks.
All source generators in FlameCsv are implemented as low-footprint incremental generators, and they include diagnostics for common pitfalls and configuration problems.
Type Map Generator
FlameCsv includes a source generator that creates code for binding .NET types to/from CSV headers. This enables writing trimmable code without any reflection or dynamic code generation — a necessity for Native AOT applications.
To use the source generator, create a partial class and apply CsvTypeMapAttribute<T, TValue>. The source generator
will inherit from CsvTypeMap<T, TValue> and generate the required code based on the attributes on the target type,
including a static property to get a thread-safe singleton instance of the type map.
[CsvTypeMap<char, User>]
partial class UserTypeMap;
// example usage
IEnumerable<User> users = CsvReader.Read(csv, UserTypeMap.Default);
The source generator has lower startup overhead than reflection, and allows debugging the code as if you wrote it yourself. All configuration is done via the options as normal.
Limitations
Due to how generic constraints and CsvConverterFactory<T> work, converter factories are not supported by the source generator.
However, since the types are known at compile time, you can add the required converters explicitly beforehand, e.g.: [CsvConverter<char, MyListConverter>].
Example
class User : IActive
{
[CsvHeader("id", "user_id")]
public int Id { get; set; }
[CsvOrder(999)]
public string? Name { get; set; }
public bool IsAdmin { get; set; }
[CsvRequired]
bool IActive.IsActive { get; set; }
}
interface IActive
{
bool IsActive { get; set; }
}
[CsvTypeMap<char, User>]
partial class UserTypeMapChar;
[CsvTypeMap<byte, User>]
partial class UserTypeMapByte;
// <auto-generated>
// Generated by FlameCsv.SourceGen v1.0.0
// </auto-generated>
// <global namespace>
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
partial class UserTypeMapChar : global::FlameCsv.Binding.CsvTypeMap<char, global::User>
{
/// <summary>
/// Returns a thread-safe instance of the typemap with default options.
/// </summary>
public static global::UserTypeMapChar Default { get; } = new global::UserTypeMapChar();
protected override global::FlameCsv.Reading.IMaterializer<char, global::User> BindForReading(global::System.Collections.Immutable.ImmutableArray<string> headers, global::FlameCsv.CsvOptions<char> options)
{
scoped global::System.ReadOnlySpan<string> headerSpan = headers.AsSpan();
TypeMapMaterializer materializer = new TypeMapMaterializer(headerSpan.Length);
global::System.StringComparison comparison = options.IgnoreHeaderCase ? global::System.StringComparison.OrdinalIgnoreCase : global::System.StringComparison.Ordinal;
bool anyBound = false;
for (int index = 0; index < headerSpan.Length; index++)
{
string name = headerSpan[index];
if ("Id".Equals(name, comparison) ||
"user_id".Equals(name, comparison))
{
if (!options.IgnoreDuplicateHeaders && materializer.@s__Converter_Id is not null)
{
base.ThrowDuplicate("Id", name, headers);
}
materializer.@s__Converter_Id = options.Aot.GetConverter<int>();
materializer.@s__Id_Id = index;
anyBound = true;
continue;
}
if ("IsAdmin".Equals(name, comparison))
{
if (!options.IgnoreDuplicateHeaders && materializer.@s__Converter_IsAdmin is not null)
{
base.ThrowDuplicate("IsAdmin", name, headers);
}
materializer.@s__Converter_IsAdmin = options.Aot.GetConverter<bool>();
materializer.@s__Id_IsAdmin = index;
anyBound = true;
continue;
}
if ("IsActive".Equals(name, comparison))
{
if (!options.IgnoreDuplicateHeaders && materializer.@s__Converter_IActive_IsActive is not null)
{
base.ThrowDuplicate("IsActive", name, headers);
}
materializer.@s__Converter_IActive_IsActive = options.Aot.GetConverter<bool>();
materializer.@s__Id_IActive_IsActive = index;
anyBound = true;
continue;
}
if ("Name".Equals(name, comparison)) // Explicit order: 999
{
if (!options.IgnoreDuplicateHeaders && materializer.@s__Converter_Name is not null)
{
base.ThrowDuplicate("Name", name, headers);
}
materializer.@s__Converter_Name = options.Aot.GetConverter<string>();
materializer.@s__Id_Name = index;
anyBound = true;
continue;
}
if (!options.IgnoreUnmatchedHeaders)
base.ThrowUnmatched(name, index, headers);
}
if (!anyBound)
{
base.ThrowNoFieldsBound(headers);
}
if (materializer.@s__Converter_IActive_IsActive is null)
{
base.ThrowRequiredNotRead(GetMissingRequiredFields(materializer), headers);
}
return materializer;
}
protected override global::FlameCsv.Reading.IMaterializer<char, global::User> BindForReading(global::FlameCsv.CsvOptions<char> options)
{
throw new global::System.NotSupportedException("No valid index binding configuration for type User.");
}
private static System.Collections.Generic.IEnumerable<string> GetMissingRequiredFields(TypeMapMaterializer materializer)
{
if (materializer.@s__Converter_IActive_IsActive is null) yield return "IActive_IsActive";
}
[global::System.Runtime.CompilerServices.SkipLocalsInit]
private struct ParseState
{
public int Id;
public bool IsAdmin;
public bool IActive_IsActive;
public string Name;
}
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal sealed partial class TypeMapMaterializer(int expectedFieldCount) : global::FlameCsv.Reading.IMaterializer<char, global::User>
{
// converters for each member/parameter
public global::FlameCsv.CsvConverter<char, int> @s__Converter_Id;
public global::FlameCsv.CsvConverter<char, bool> @s__Converter_IsAdmin;
public global::FlameCsv.CsvConverter<char, bool> @s__Converter_IActive_IsActive; // required
public global::FlameCsv.CsvConverter<char, string> @s__Converter_Name;
// field indexes in the current CSV
public int @s__Id_Id;
public int @s__Id_IsAdmin;
public int @s__Id_IActive_IsActive;
public int @s__Id_Name;
[global::System.Runtime.CompilerServices.SkipLocalsInit]
public global::User Parse(global::FlameCsv.Reading.CsvRecordRef<char> record)
{
if (record.FieldCount != expectedFieldCount)
{
global::FlameCsv.Exceptions.CsvReadException.ThrowForInvalidFieldCount(expectedFieldCount, record);
}
int __index;
#if RELEASE
global::System.Runtime.CompilerServices.Unsafe.SkipInit(out ParseState state);
#else
ParseState state = default;
#endif
if (!@s__Converter_IActive_IsActive.TryParse(record.GetFieldUnsafe(__index = @s__Id_IActive_IsActive), out state.IActive_IsActive))
{
goto FailedParse;
}
global::User obj = new global::User();
((global::IActive)obj).IsActive = state.IActive_IsActive;
if (@s__Converter_Id is not null)
{
if (!@s__Converter_Id.TryParse(record.GetFieldUnsafe(__index = @s__Id_Id), out state.Id))
{
goto FailedParse;
}
obj.Id = state.Id;
}
if (@s__Converter_IsAdmin is not null)
{
if (!@s__Converter_IsAdmin.TryParse(record.GetFieldUnsafe(__index = @s__Id_IsAdmin), out state.IsAdmin))
{
goto FailedParse;
}
obj.IsAdmin = state.IsAdmin;
}
if (@s__Converter_Name is not null)
{
if (!@s__Converter_Name.TryParse(record.GetFieldUnsafe(__index = @s__Id_Name), out state.Name))
{
goto FailedParse;
}
obj.Name = state.Name;
}
return obj;
FailedParse:
ThrowForFailedParse(__index);
return default; // Unreachable
}
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private void ThrowForFailedParse(int index)
{
if (index == @s__Id_Id) global::FlameCsv.Exceptions.CsvParseException.Throw(index, typeof(int), @s__Converter_Id, "Id");
if (index == @s__Id_IsAdmin) global::FlameCsv.Exceptions.CsvParseException.Throw(index, typeof(bool), @s__Converter_IsAdmin, "IsAdmin");
if (index == @s__Id_IActive_IsActive) global::FlameCsv.Exceptions.CsvParseException.Throw(index, typeof(bool), @s__Converter_IActive_IsActive, "IsActive");
if (index == @s__Id_Name) global::FlameCsv.Exceptions.CsvParseException.Throw(index, typeof(string), @s__Converter_Name, "Name");
throw new global::System.Diagnostics.UnreachableException("Invalid target index: " + index.ToString());
}
}
protected override global::FlameCsv.Writing.IDematerializer<char, global::User> BindForWriting(global::FlameCsv.CsvOptions<char> options)
{
if (options.HasHeader)
{
return new TypeMapDematerializer
{
@s__Converter_Id = options.Aot.GetConverter<int>(),
@s__Converter_IsAdmin = options.Aot.GetConverter<bool>(),
@s__Converter_IActive_IsActive = options.Aot.GetConverter<bool>(),
@s__Converter_Name = options.Aot.GetConverter<string>(),
};
}
throw new global::System.NotSupportedException("No valid index binding configuration for type User.");
}
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal sealed partial class TypeMapDematerializer : global::FlameCsv.Writing.IDematerializer<char, global::User>
{
public int FieldCount => 4;
public required global::FlameCsv.CsvConverter<char, int> @s__Converter_Id { get; init; }
public required global::FlameCsv.CsvConverter<char, bool> @s__Converter_IsAdmin { get; init; }
public required global::FlameCsv.CsvConverter<char, bool> @s__Converter_IActive_IsActive { get; init; }
public required global::FlameCsv.CsvConverter<char, string> @s__Converter_Name { get; init; }
[global::System.Runtime.CompilerServices.SkipLocalsInit]
public void Write(global::FlameCsv.Writing.CsvFieldWriter<char> writer, global::User obj)
{
writer.WriteField(@s__Converter_Id, obj.Id);
writer.WriteDelimiter();
writer.WriteField(@s__Converter_IsAdmin, obj.IsAdmin);
writer.WriteDelimiter();
writer.WriteField(@s__Converter_IActive_IsActive, ((global::IActive)obj).IsActive);
writer.WriteDelimiter();
writer.WriteField(@s__Converter_Name, obj.Name);
}
[global::System.Runtime.CompilerServices.SkipLocalsInit]
public void WriteHeader(global::FlameCsv.Writing.CsvFieldWriter<char> writer)
{
writer.WriteRaw("Id");
writer.WriteDelimiter();
writer.WriteRaw("IsAdmin");
writer.WriteDelimiter();
writer.WriteRaw("IsActive");
writer.WriteDelimiter();
writer.WriteRaw("Name");
}
}
}
Enum Converter Generator
CsvEnumConverterAttribute<T, TEnum> can be used to generate extremely performant enum converters that are essentially hyper-optimized hand-written implementations specific to the enum. The implementations use very low-level code to optimize for performance.
Simply apply the attribute to a partial class. The generated converter supports parsing and formatting numbers, enum names, flags-enums,
[EnumMemberAttribute], and case-insensitive parsing of both UTF-16 and UTF-8 data.
The converter also correctly handles oddities on both UTF-8 and UTF-16, such as surrogates and non-ASCII data like emojis,
and intelligently switches between raw byte/memory manipulation and transcoding to chars when necessary.
[CsvEnumConverter<char, DayOfWeek>]
partial class DayOfWeekConverter;
Limitations
- Hex-formatted values are not supported; the generator will defer to
Enum.TryFormatandEnum.TryParse - Custom enum names must not start with a digit or a dash (minus sign)
- Custom names must not be empty, or have duplicates among enum names.
- Cultures with custom number formatting rules are not supported; the generator always uses the invariant culture
Example
Below is an example of the code generated by the source generator for TypeCode. The actual generated code may differ in practice.
// <auto-generated>
// Generated by FlameCsv.SourceGen v1.0.0
// </auto-generated>
#nullable enable
using __Unsafe = global::System.Runtime.CompilerServices.Unsafe;
using __MemoryMarshal = global::System.Runtime.InteropServices.MemoryMarshal;
using __BP = global::System.Buffers.Binary.BinaryPrimitives;
// <global namespace>
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.Runtime.CompilerServices.SkipLocalsInit]
partial class TypeCodeCharConverter : global::FlameCsv.CsvConverter<char, global::System.TypeCode>
{
private static WriteNumberImpl WriteNumberStrategy { get; } = new();
private static WriteStringImpl WriteStringStrategy { get; } = new();
private static ReadOrdinalImpl OrdinalStrategy { get; } = new();
private static ReadIgnoreCaseImpl IgnoreCaseStrategy { get; } = new();
private readonly global::FlameCsv.Converters.Enums.EnumParseStrategy<char, global::System.TypeCode> _parseStrategy;
private readonly global::FlameCsv.Converters.Enums.EnumFormatStrategy<char, global::System.TypeCode> _formatStrategy;
private readonly bool _allowUndefinedValues;
private readonly bool _ignoreCase;
private readonly string? _format;
public TypeCodeCharConverter(global::FlameCsv.CsvOptions<char> options)
{
global::System.ArgumentNullException.ThrowIfNull(options);
_allowUndefinedValues = options.AllowUndefinedEnumValues;
_ignoreCase = options.IgnoreEnumCase;
_format = options.GetFormat(typeof(global::System.TypeCode), options.EnumFormat);
_parseStrategy = _ignoreCase ? IgnoreCaseStrategy : OrdinalStrategy;
_formatStrategy = _format switch
{
null or "g" or "G" => WriteStringStrategy,
"d" or "D" => WriteNumberStrategy,
"x" or "X" => global::FlameCsv.Converters.Enums.EnumFormatStrategy<char, global::System.TypeCode>.None, // always defer to Enum.TryFormat
"f" or "F" => throw new global::System.NotSupportedException("Flags-format not supported for non-flags enum TypeCode"),
{ } configuredFormat => throw new global::System.NotSupportedException("Invalid enum format specified: " + configuredFormat)
};
}
public override bool TryParse(global::System.ReadOnlySpan<char> source, out global::System.TypeCode value)
{
if (source.IsEmpty)
{
__Unsafe.SkipInit(out value);
return false;
}
ref char first = ref __MemoryMarshal.GetReference(source);
// check if value starts with a digit
if ((uint)(first - '0') <= 9u)
{
switch (source.Length)
{
case 1:
{
// all values in the 0..9 range are valid
value = (global::System.TypeCode)(uint)(first - '0');
return true;
}
case 2:
{
if (first == '1')
{
switch (source[1])
{
case '0': value = (global::System.TypeCode)10; return true;
case '1': value = (global::System.TypeCode)11; return true;
case '2': value = (global::System.TypeCode)12; return true;
case '3': value = (global::System.TypeCode)13; return true;
case '4': value = (global::System.TypeCode)14; return true;
case '5': value = (global::System.TypeCode)15; return true;
case '6': value = (global::System.TypeCode)16; return true;
case '8': value = (global::System.TypeCode)18; return true;
}
}
break;
}
}
}
else if (_parseStrategy.TryParse(source, out value))
{
return true;
}
// unknown value, defer to Enum.TryParse
return global::System.Enum.TryParse(source, _ignoreCase, out value)
&& (_allowUndefinedValues || IsDefined(value));
}
public override bool TryFormat(global::System.Span<char> destination, global::System.TypeCode value, out int charsWritten)
{
if (destination.IsEmpty)
{
__Unsafe.SkipInit(out charsWritten);
return false;
}
global::System.Buffers.OperationStatus status = _formatStrategy.TryFormat(destination, value, out charsWritten);
if (status == global::System.Buffers.OperationStatus.Done) return true;
if (status == global::System.Buffers.OperationStatus.DestinationTooSmall) return false;
// unknown value, defer to Enum.TryFormat
return ((global::System.ISpanFormattable)value).TryFormat(destination, out charsWritten, _format, provider: null);
}
/// <summary>
/// Determines whether a specified value is defined for the enumeration.
/// </summary>
public static bool IsDefined(global::System.TypeCode value)
{
return value
is global::System.TypeCode.Empty
or global::System.TypeCode.Object
or global::System.TypeCode.DBNull
or global::System.TypeCode.Boolean
or global::System.TypeCode.Char
or global::System.TypeCode.SByte
or global::System.TypeCode.Byte
or global::System.TypeCode.Int16
or global::System.TypeCode.UInt16
or global::System.TypeCode.Int32
or global::System.TypeCode.UInt32
or global::System.TypeCode.Int64
or global::System.TypeCode.UInt64
or global::System.TypeCode.Single
or global::System.TypeCode.Double
or global::System.TypeCode.Decimal
or global::System.TypeCode.DateTime
or global::System.TypeCode.String;
}
/// <summary>
/// Case-sensitive parsing strategy.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.Runtime.CompilerServices.SkipLocalsInit]
private sealed class ReadOrdinalImpl : global::FlameCsv.Converters.Enums.EnumParseStrategy<char, global::System.TypeCode>
{
public override bool TryParse(global::System.ReadOnlySpan<char> source, out global::System.TypeCode value)
{
ref char first = ref __MemoryMarshal.GetReference(source);
switch (source.Length)
{
case 5:
{
switch (first)
{
case 'I':
{
if (global::System.MemoryExtensions.EndsWith(source, "nt16", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Int16;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "nt32", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Int32;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "nt64", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Int64;
return true;
}
break;
}
case 'E':
{
if (global::System.MemoryExtensions.EndsWith(source, "mpty", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Empty;
return true;
}
break;
}
case 'S':
{
if (global::System.MemoryExtensions.EndsWith(source, "Byte", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.SByte;
return true;
}
break;
}
}
break;
}
case 6:
{
switch (first)
{
case 'U':
{
if (global::System.MemoryExtensions.EndsWith(source, "Int16", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.UInt16;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "Int32", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.UInt32;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "Int64", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.UInt64;
return true;
}
break;
}
case 'D':
{
if (global::System.MemoryExtensions.EndsWith(source, "BNull", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.DBNull;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "ouble", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Double;
return true;
}
break;
}
case 'S':
{
if (global::System.MemoryExtensions.EndsWith(source, "ingle", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Single;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "tring", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.String;
return true;
}
break;
}
case 'O':
{
if (global::System.MemoryExtensions.EndsWith(source, "bject", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Object;
return true;
}
break;
}
}
break;
}
case 7:
{
if (global::System.MemoryExtensions.Equals(source, "Boolean", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Boolean;
return true;
}
if (global::System.MemoryExtensions.Equals(source, "Decimal", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Decimal;
return true;
}
break;
}
case 4:
{
if (global::System.MemoryExtensions.Equals(source, "Char", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Char;
return true;
}
if (global::System.MemoryExtensions.Equals(source, "Byte", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.Byte;
return true;
}
break;
}
case 8:
{
if (global::System.MemoryExtensions.Equals(source, "DateTime", global::System.StringComparison.Ordinal))
{
value = global::System.TypeCode.DateTime;
return true;
}
break;
}
default:
break;
}
__Unsafe.SkipInit(out value);
return false;
}
}
/// <summary>
/// Case-insensitive parsing strategy.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.Runtime.CompilerServices.SkipLocalsInit]
private sealed class ReadIgnoreCaseImpl : global::FlameCsv.Converters.Enums.EnumParseStrategy<char, global::System.TypeCode>
{
public override bool TryParse(global::System.ReadOnlySpan<char> source, out global::System.TypeCode value)
{
ref char first = ref __MemoryMarshal.GetReference(source);
switch (source.Length)
{
case 5:
{
switch ((char)(first | 0x20))
{
case 'i':
{
if (global::System.MemoryExtensions.EndsWith(source, "nt16", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Int16;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "nt32", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Int32;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "nt64", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Int64;
return true;
}
break;
}
case 'e':
{
if (global::System.MemoryExtensions.EndsWith(source, "mpty", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Empty;
return true;
}
break;
}
case 's':
{
if (global::System.MemoryExtensions.EndsWith(source, "Byte", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.SByte;
return true;
}
break;
}
}
break;
}
case 6:
{
switch ((char)(first | 0x20))
{
case 'u':
{
if (global::System.MemoryExtensions.EndsWith(source, "Int16", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.UInt16;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "Int32", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.UInt32;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "Int64", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.UInt64;
return true;
}
break;
}
case 'd':
{
if (global::System.MemoryExtensions.EndsWith(source, "BNull", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.DBNull;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "ouble", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Double;
return true;
}
break;
}
case 's':
{
if (global::System.MemoryExtensions.EndsWith(source, "ingle", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Single;
return true;
}
if (global::System.MemoryExtensions.EndsWith(source, "tring", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.String;
return true;
}
break;
}
case 'o':
{
if (global::System.MemoryExtensions.EndsWith(source, "bject", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Object;
return true;
}
break;
}
}
break;
}
case 7:
{
if (global::System.MemoryExtensions.Equals(source, "Boolean", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Boolean;
return true;
}
if (global::System.MemoryExtensions.Equals(source, "Decimal", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Decimal;
return true;
}
break;
}
case 4:
{
if (global::System.MemoryExtensions.Equals(source, "Char", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Char;
return true;
}
if (global::System.MemoryExtensions.Equals(source, "Byte", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.Byte;
return true;
}
break;
}
case 8:
{
if (global::System.MemoryExtensions.Equals(source, "DateTime", global::System.StringComparison.OrdinalIgnoreCase))
{
value = global::System.TypeCode.DateTime;
return true;
}
break;
}
default:
break;
}
__Unsafe.SkipInit(out value);
return false;
}
}
/// <summary>
/// Formatting strategy for writing numeric values.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.Runtime.CompilerServices.SkipLocalsInit]
private sealed class WriteNumberImpl : global::FlameCsv.Converters.Enums.EnumFormatStrategy<char, global::System.TypeCode>
{
public override global::System.Buffers.OperationStatus TryFormat(global::System.Span<char> destination, global::System.TypeCode value, out int charsWritten)
{
__Unsafe.SkipInit(out charsWritten);
ref char dst = ref destination[0];
if ((ulong)value < 10)
{
dst = (char)('0' + (uint)value);
charsWritten = 1;
return global::System.Buffers.OperationStatus.Done;
}
if (destination.Length >= 2)
{
switch (value)
{
case global::System.TypeCode.UInt32:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("10"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.Int64:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("11"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.UInt64:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("12"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.Single:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("13"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.Double:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("14"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.Decimal:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("15"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.DateTime:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("16"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
case global::System.TypeCode.String:
{
__Unsafe.As<char, uint>(ref dst) = __Unsafe.As<char, uint>(ref __MemoryMarshal.GetReference<char>("18"));
charsWritten = 2;
return global::System.Buffers.OperationStatus.Done;
}
}
// unknown value
return global::System.Buffers.OperationStatus.InvalidData;
}
else
{
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
}
}
/// <summary>
/// Formatting strategy for writing enum names.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("FlameCsv.SourceGen", "1.0.0")]
[global::System.Runtime.CompilerServices.SkipLocalsInit]
private sealed class WriteStringImpl : global::FlameCsv.Converters.Enums.EnumFormatStrategy<char, global::System.TypeCode>
{
public override global::System.Buffers.OperationStatus TryFormat(global::System.Span<char> destination, global::System.TypeCode value, out int charsWritten)
{
__Unsafe.SkipInit(out charsWritten);
ref char dst = ref destination[0];
switch (value)
{
case global::System.TypeCode.Empty:
{
if ("Empty".TryCopyTo(destination))
{
charsWritten = 5;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Object:
{
if ("Object".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.DBNull:
{
if ("DBNull".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Boolean:
{
if ("Boolean".TryCopyTo(destination))
{
charsWritten = 7;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Char:
{
if (destination.Length >= 4)
{
__Unsafe.As<char, ulong>(ref dst) = __Unsafe.As<char, ulong>(ref __MemoryMarshal.GetReference<char>("Char"));
charsWritten = 4;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.SByte:
{
if ("SByte".TryCopyTo(destination))
{
charsWritten = 5;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Byte:
{
if (destination.Length >= 4)
{
__Unsafe.As<char, ulong>(ref dst) = __Unsafe.As<char, ulong>(ref __MemoryMarshal.GetReference<char>("Byte"));
charsWritten = 4;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Int16:
{
if ("Int16".TryCopyTo(destination))
{
charsWritten = 5;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.UInt16:
{
if ("UInt16".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Int32:
{
if ("Int32".TryCopyTo(destination))
{
charsWritten = 5;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.UInt32:
{
if ("UInt32".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Int64:
{
if ("Int64".TryCopyTo(destination))
{
charsWritten = 5;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.UInt64:
{
if ("UInt64".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Single:
{
if ("Single".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Double:
{
if ("Double".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.Decimal:
{
if ("Decimal".TryCopyTo(destination))
{
charsWritten = 7;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.DateTime:
{
if ("DateTime".TryCopyTo(destination))
{
charsWritten = 8;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
case global::System.TypeCode.String:
{
if ("String".TryCopyTo(destination))
{
charsWritten = 6;
return global::System.Buffers.OperationStatus.Done;
}
return global::System.Buffers.OperationStatus.DestinationTooSmall;
}
}
// unknown value
return global::System.Buffers.OperationStatus.InvalidData;
}
}
}