<commit_before>﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;

namespace Narochno.Primitives.Parsing.Parsers
{
    public class EnumParser : Parser<Enum>
    {
        public Type Type { get; }
        public IList<Enum> Values { get; } = new List<Enum>();
        public IDictionary<Enum, string> EnumStrings { get; } = new Dictionary<Enum, string>();

        public EnumParser(Type type)
        {
            Type = type;
            foreach (var value in Enum.GetValues(type))
            {
                Values.Add((Enum)value);
            }

            // Cache this as it's expensive to fetch
            foreach (var value in Values)
            {
                foreach (var attribute in Type.GetField(Enum.GetName(Type, value))
                    .GetCustomAttributes<EnumMemberAttribute>())
                {
                    EnumStrings.Add(value, attribute.Value);
                }
            }
        }

        public override Enum Parse(string input)
        {
            // First try to get the fields with EnumMemberAttribute
            foreach (var value in Values)
            {
                if (EnumStrings.ContainsKey(value)
                    && EnumStrings[value].Equals(input))
                {
                    return value;
                }
            }

            // Fallback to the real Enum.Parse
            return (Enum)Enum.Parse(Type, input);
        }

        public override Optional<Enum> TryParse(string input)
        {
            // First try to get the fields with EnumMemberAttribute
            foreach (var value in Values)
            {
                if (EnumStrings.ContainsKey(value)
                    && EnumStrings[value].Equals(input))
                {
                    return value;
                }
            }

            // Fallback to a try parse (we can't use the
            // real TryParse here as it has type parameters)
            foreach (var value in Values)
            {
                if (Enum.GetName(Type, value).Equals(input))
                {
                    return value;
                }
            }

            return new Optional<Enum>();
        }
    }
}<commit_msg>Tweak to EnumParser to make code clearer and better utilise the cached dict.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;

namespace Narochno.Primitives.Parsing.Parsers
{
    public class EnumParser : Parser<Enum>
    {
        public Type Type { get; }
        public IList<Enum> Values { get; } = new List<Enum>();
        public IDictionary<string, Enum> EnumStrings { get; } = new Dictionary<string, Enum>();

        public EnumParser(Type type)
        {
            Type = type;
            foreach (var value in Enum.GetValues(type))
            {
                Values.Add((Enum)value);
            }

            // Cache this as it's expensive to fetch
            foreach (var value in Values)
            {
                foreach (var attribute in Type.GetField(Enum.GetName(Type, value))
                    .GetCustomAttributes<EnumMemberAttribute>())
                {
                    EnumStrings.Add(attribute.Value, value);
                }
            }
        }

        public override Enum Parse(string input)
        {
            // First try to get the fields with EnumMemberAttribute
            if (input != null && EnumStrings.ContainsKey(input))
            {
                return EnumStrings[input];
            }

            // Fallback to the real Enum.Parse
            return (Enum)Enum.Parse(Type, input);
        }

        public override Optional<Enum> TryParse(string input)
        {
            // First try to get the fields with EnumMemberAttribute
            if (input != null && EnumStrings.ContainsKey(input))
            {
                return EnumStrings[input];
            }

            // Fallback to a try parse (we can't use the
            // real TryParse here as it has type parameters)
            foreach (var value in Values)
            {
                if (Enum.GetName(Type, value).Equals(input))
                {
                    return value;
                }
            }

            return new Optional<Enum>();
        }
    }
}
{'fraction_non_alphanumeric': 0.0843096714909258, 'fraction_numerical': 0.0, 'mean_word_length': 1.3949394939493949, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6032650', 'n_tokens_mistral': 1075, 'n_tokens_neox': 1014, 'n_words': 300}