Table of Contents

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.TryFormat and Enum.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;
        }
    }
}