{"id":30759061,"url":"https://github.com/snowberry-software/EnumsEnhanced","last_synced_at":"2025-09-04T12:03:07.825Z","repository":{"id":37427106,"uuid":"465524759","full_name":"snowberry-software/EnumsEnhanced","owner":"snowberry-software","description":"Source generator for generating common (extension) methods for enums without having the cost of the Reflection API.","archived":false,"fork":false,"pushed_at":"2025-03-04T12:15:19.000Z","size":94,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-12T12:12:08.053Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snowberry-software.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.txt","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-03T01:22:06.000Z","updated_at":"2025-03-04T12:14:11.000Z","dependencies_parsed_at":"2024-04-07T05:27:10.218Z","dependency_job_id":"ef9e77bc-3ead-4ead-a061-c92832108ec6","html_url":"https://github.com/snowberry-software/EnumsEnhanced","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/snowberry-software/EnumsEnhanced","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowberry-software%2FEnumsEnhanced","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowberry-software%2FEnumsEnhanced/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowberry-software%2FEnumsEnhanced/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowberry-software%2FEnumsEnhanced/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snowberry-software","download_url":"https://codeload.github.com/snowberry-software/EnumsEnhanced/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowberry-software%2FEnumsEnhanced/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272809887,"owners_count":24996630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-04T12:01:27.772Z","updated_at":"2025-09-04T12:03:07.811Z","avatar_url":"https://github.com/snowberry-software.png","language":"C#","funding_links":[],"categories":["Content"],"sub_categories":["217. [EnumsEnhanced](https://ignatandrei.github.io/RSCG_Examples/v2/docs/EnumsEnhanced) , in the [Enum](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enum) category"],"readme":"[![License](https://img.shields.io/github/license/snowberry-software/EnumsEnhanced)](https://github.com/snowberry-software/EnumsEnhanced/blob/master/LICENSE)\n[![NuGet Version](https://img.shields.io/nuget/v/EnumsEnhanced.svg?logo=nuget)](https://www.nuget.org/packages/EnumsEnhanced/)\n\n# EnumsEnhanced\n\n`EnumsEnhanced` is a C# [source generator](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators) for generating common (extension) methods for enums without having the cost of the Reflection API (slow and many allocations).\n\nFollowing extension methods will be generated for each enum:\n\n| Default   | Equivalent                 |\n| --------- | -------------------------- |\n| GetName   | GetNameFast                |\n| GetNames  | GetNamesFast               |\n| GetValues | GetValuesFast              |\n| HasFlag   | HasFlagFast, HasFlagUnsafe |\n| IsDefined | IsDefinedFast              |\n| Parse     | ParseFast                  |\n| TryParse  | TryParseFast               |\n| ToString  | ToStringFast               |\n\n# How to use it\n\nThe project that makes use of this package must enable `AllowUnsafeBlocks` in order to allow compiling the `HasFlagUnsafe` extension method.\n\nAlso it will only generate the extension methods if the enum has no containing type.\n\n```cs\ninternal class EnumContainingTypeTest\n{\n    // Will not generate any code for this enum.\n    public enum ContainingTypeEnum\n    {\n        Test1\n    }\n}\n```\n\nThe generated class will always have the same naming scheme by using your enum type name with an `Enhanced` postfix (e.g. **YourEnumName**`Enhanced`)\nor in this example **TestEnumEnhanced**.\n\n```cs\nnamespace EnumsEnhancedTest;\n\n[Flags]\ninternal enum TestEnum\n{\n    Test1 = 1 \u003c\u003c 0,\n    Test_1 = 1 \u003c\u003c 0,\n\n    Test2 = 1 \u003c\u003c 1,\n    Test4 = 1 \u003c\u003c 2,\n    Test5 = 1 \u003c\u003c 4,\n    Test6 = 1 \u003c\u003c 6,\n    Test7\n}\n```\n\nGenerated code:\n\n```cs\n#nullable enable\n\nusing System.Text;\nusing System.Runtime.CompilerServices;\nusing System.Collections.Generic;\nusing System;\nusing System;\nusing System.Globalization;\n\nnamespace EnumsEnhancedTest {\n  /// \u003csummary\u003e\n  /// Reflection free extension methods for the \u003csee cref=\"TestEnum\"/\u003e type.\n  /// \u003c/summary\u003e\n  internal static partial class TestEnumEnhanced {\n\n    /// \u003csummary\u003e\n    /// Determines whether one or more bit fields are set in the current instance.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"e\"\u003eThe value of the enum.\u003c/param\u003e\n    /// \u003cparam name=\"flag\"\u003eThe flag to check.\u003c/param\u003e\n    /// \u003creturns\u003e\u003csee langword=\"true\"/\u003e if the bit field or bit fields that are set in flag are also set in the current instance; otherwise, false.\u003c/returns\u003e\n    #if NETCOREAPP3_0_OR_GREATER\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    #else\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]\n    #endif\n\n    public static bool HasFlagFast(this TestEnum e, TestEnum flag) {\n      return (e \u0026 flag) == flag;\n    }\n\n    /// \u003cinheritdoc cref=\"HasFlagFast(TestEnum, TestEnum)\"/\u003e\n    #if NETCOREAPP3_0_OR_GREATER\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    #else\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]\n    #endif\n\n    public static unsafe bool HasFlagFastUnsafe(this TestEnum e, TestEnum flag) {\n      return HasFlagFastUnsafe( \u0026 e, \u0026 flag);\n    }\n\n    /// \u003csummary\u003e\n    /// Determines whether one or more bit fields are set in the current instance using unsafe pointer type casting.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"e\"\u003eThe value of the enum.\u003c/param\u003e\n    /// \u003cparam name=\"flag\"\u003eThe flag to check.\u003c/param\u003e\n    /// \u003creturns\u003e\u003csee langword=\"true\"/\u003e if the bit field or bit fields that are set in flag are also set in the current instance; otherwise, false.\u003c/returns\u003e\n    #if NETCOREAPP3_0_OR_GREATER\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    #else\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]\n    #endif\n\n    public static unsafe bool HasFlagFastUnsafe(TestEnum * e, TestEnum * flag) {\n      return ( * (int * ) e \u0026 * (int * ) flag) == * (int * ) flag;\n    }\n\n    /// \u003csummary\u003e\n    /// Retrieves an array of the names of the constants.\n    /// \u003c/summary\u003e\n    /// \u003creturns\u003eA string array of the names of the constants.\u003c/returns\u003e\n    public static string[] GetNamesFast() {\n      return new string[] {\n        \"Test1\",\n        \"Test_1\",\n        \"Test2\",\n        \"Test4\",\n        \"Test5\",\n        \"Test6\",\n        \"Test7\"\n      };\n    }\n\n    /// \u003csummary\u003e\n    /// Retrieves an array of the values of the constants.\n    /// \u003c/summary\u003e\n    /// \u003creturns\u003eAn array that contains the values of the constants.\u003c/returns\u003e\n    public static TestEnum[] GetValuesFast() {\n      return new TestEnum[] {\n        TestEnum.Test1, TestEnum.Test_1, TestEnum.Test2, TestEnum.Test4, TestEnum.Test5, TestEnum.Test6, TestEnum.Test7\n      };\n    }\n\n    /// \u003cinheritdoc cref=\"IsDefinedFast(TestEnum)\"/\u003e\n    public static bool IsDefinedFast(string value) {\n      _ = value ??\n        throw new ArgumentNullException(nameof(value));\n\n      switch (value) {\n      case \"Test1\":\n        return true;\n      case \"Test2\":\n        return true;\n      case \"Test4\":\n        return true;\n      case \"Test5\":\n        return true;\n      case \"Test6\":\n        return true;\n      case \"Test7\":\n        return true;\n      case \"Test_1\":\n        return true;\n\n      }\n\n      return false;\n    }\n\n    /// \u003cinheritdoc cref=\"IsDefinedFast(TestEnum)\"/\u003e\n    #if NETCOREAPP3_0_OR_GREATER\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    #else\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]\n    #endif\n\n    public static bool IsDefinedFast(Int32 value) {\n      return IsDefinedFast((TestEnum) value);\n    }\n\n    /// \u003csummary\u003e\n    /// Returns a \u003csee cref=\"bool\"/\u003e telling whether its given value exists in the enumeration.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"value\"\u003eThe value of the enumeration constant.\u003c/param\u003e\n    /// \u003creturns\u003e\u003csee langword=\"true\"/\u003e if a constant is defined with the given value from the \u003cparamref name=\"value\"/\u003e.\u003c/returns\u003e\n    public static bool IsDefinedFast(TestEnum value) {\n      switch (value) {\n      case TestEnum.Test1:\n        return true;\n      case TestEnum.Test2:\n        return true;\n      case TestEnum.Test4:\n        return true;\n      case TestEnum.Test5:\n        return true;\n      case TestEnum.Test6:\n        return true;\n      case TestEnum.Test7:\n        return true;\n        // Skipping duplicated constant value: TestEnum.Test_1 -\u003e 1\n\n      }\n\n      return false;\n    }\n\n    /// \u003csummary\u003e\n    /// Resolves the name of the given enum value.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"e\"\u003eThe value of a particular enumerated constant in terms of its underlying type.\u003c/param\u003e\n    /// \u003cparam name=\"includeFlagNames\"\u003eDetermines whether the value has flags, so it will return `EnumValue, EnumValue2`.\u003c/param\u003e\n    /// \u003creturns\u003e A string containing the name of the enumerated constant or \u003csee langword=\"null\"/\u003e if the enum has multiple flags set but \u003cparamref name=\"includeFlagNames\"/\u003e is not enabled.\u003c/returns\u003e\n    public static string ? GetNameFast(this TestEnum e, bool includeFlagNames = false) {\n      switch (e) {\n      case TestEnum.Test1:\n        return nameof(TestEnum.Test1);\n\n        // Skipping duplicated constant value: TestEnum.Test_1 -\u003e 1\n\n      case TestEnum.Test2:\n        return nameof(TestEnum.Test2);\n\n      case TestEnum.Test4:\n        return nameof(TestEnum.Test4);\n\n      case TestEnum.Test5:\n        return nameof(TestEnum.Test5);\n\n      case TestEnum.Test6:\n        return nameof(TestEnum.Test6);\n\n      case TestEnum.Test7:\n        return nameof(TestEnum.Test7);\n\n      }\n\n      // Returning null is the default behavior.\n      if (!includeFlagNames)\n        return null;\n      //throw new Exception(\"Enum name could not be found!\");\n\n      var flagBuilder = new StringBuilder();\n      if (e.HasFlagFast(TestEnum.Test1))\n        flagBuilder.Append(TestEnum.Test1.GetNameFast(false) + \", \");\n\n      // Skipping duplicated constant value: TestEnum.Test_1 -\u003e 1\n\n      if (e.HasFlagFast(TestEnum.Test2))\n        flagBuilder.Append(TestEnum.Test2.GetNameFast(false) + \", \");\n\n      if (e.HasFlagFast(TestEnum.Test4))\n        flagBuilder.Append(TestEnum.Test4.GetNameFast(false) + \", \");\n\n      if (e.HasFlagFast(TestEnum.Test5))\n        flagBuilder.Append(TestEnum.Test5.GetNameFast(false) + \", \");\n\n      if (e.HasFlagFast(TestEnum.Test6))\n        flagBuilder.Append(TestEnum.Test6.GetNameFast(false) + \", \");\n\n      if (e.HasFlagFast(TestEnum.Test7))\n        flagBuilder.Append(TestEnum.Test7.GetNameFast(false) + \", \");\n\n      return flagBuilder.ToString().Trim(new char[] {\n        ',',\n        ' '\n      });\n    }\n\n    /// \u003csummary\u003e\n    /// Converts the value of this instance to its equivalent string representation.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"e\"\u003eThe value of a particular enumerated constant in terms of its underlying type.\u003c/param\u003e\n    /// \u003creturns\u003eThe string representation of the value of this instance.\u003c/returns\u003e\n    #if NETCOREAPP3_0_OR_GREATER\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    #else\n      [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]\n    #endif\n\n    public static string ? ToStringFast(this TestEnum e) {\n      return GetNameFast(e, true);\n    }\n\n    /// \u003csummary\u003e\n    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"value\"\u003eA string containing the name or value to convert.\u003c/param\u003e\n    /// \u003cparam name=\"ignoreCase\"\u003e\u003csee langword=\"true\"/\u003e to ignore case; false to regard case.\u003c/param\u003e\n    /// \u003cparam name=\"result\"\u003eThe result of the enumeration constant.\u003c/param\u003e\n    /// \u003creturns\u003e\u003csee langword=\"true\"/\u003e if the conversion succeeded; \u003csee langword=\"false\"/\u003e otherwise.\u003c/returns\u003e\n    public static bool TryParseFast(string value, bool ignoreCase, out TestEnum result) {\n      result = ParseFast(out\n        var successful, value: value, ignoreCase: ignoreCase, throwOnFailure: false);\n      return successful;\n    }\n\n    /// \u003csummary\u003e\n    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"value\"\u003eA string containing the name or value to convert.\u003c/param\u003e\n    /// \u003cparam name=\"ignoreCase\"\u003e\u003csee langword=\"true\"/\u003e to ignore case; false to regard case.\u003c/param\u003e\n    /// \u003creturns\u003eThe enumeration value whose value is represented by the given value.\u003c/returns\u003e\n    public static TestEnum ParseFast(string value, bool ignoreCase = false) {\n      return ParseFast(out _, value: value, ignoreCase: ignoreCase, throwOnFailure: true);\n    }\n\n    /// \u003csummary\u003e\n    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"successful\"\u003e\u003csee langword=\"true\"/\u003e if the conversion succeeded; \u003csee langword=\"false\"/\u003e otherwise.\u003c/param\u003e\n    /// \u003cparam name=\"value\"\u003eA string containing the name or value to convert.\u003c/param\u003e\n    /// \u003cparam name=\"ignoreCase\"\u003e\u003csee langword=\"true\"/\u003e to ignore case; false to regard case.\u003c/param\u003e\n    /// \u003cparam name=\"throwOnFailure\"\u003eDetermines whether to throw an \u003csee cref=\"Exception\"/\u003e on errors or not.\u003c/param\u003e\n    /// \u003creturns\u003eThe enumeration value whose value is represented by the given value.\u003c/returns\u003e\n    public static TestEnum ParseFast(out bool successful, string value, bool ignoreCase = false, bool throwOnFailure = true) {\n      successful = false;\n\n      if (throwOnFailure \u0026\u0026 (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value))) {\n        throw new ArgumentException(\"Value can't be null or whitespace!\", nameof(value));\n      }\n\n      Int32 localResult = 0;\n      bool parsed = false;\n      string subValue;\n      string originalValue = value;\n      char firstChar = value[0];\n\n      if (char.IsDigit(firstChar) || firstChar == '-' || firstChar == '+') {\n        if (Int32.TryParse(value, NumberStyles.AllowLeadingSign | NumberStyles.AllowTrailingWhite, null, out\n            var valueNumber))\n          switch (valueNumber) {\n          case (Int32) TestEnum.Test1:\n            successful = true;\n            return TestEnum.Test1;\n\n          case (Int32) TestEnum.Test2:\n            successful = true;\n            return TestEnum.Test2;\n\n          case (Int32) TestEnum.Test4:\n            successful = true;\n            return TestEnum.Test4;\n\n          case (Int32) TestEnum.Test5:\n            successful = true;\n            return TestEnum.Test5;\n\n          case (Int32) TestEnum.Test6:\n            successful = true;\n            return TestEnum.Test6;\n\n          case (Int32) TestEnum.Test7:\n            successful = true;\n            return TestEnum.Test7;\n\n            // Skipping duplicated constant value: TestEnum.Test_1 -\u003e 1\n\n          }\n      } else\n        while (value != null \u0026\u0026 value.Length \u003e 0) {\n          parsed = false;\n\n          int endIndex = value.IndexOf(',');\n\n          if (endIndex \u003c 0) {\n            // No next separator; use the remainder as the next value.\n            subValue = value.Trim();\n            value = null!;\n          } else if (endIndex != value!.Length - 1) {\n            // Found a separator before the last char.\n            subValue = value.Substring(0, endIndex).Trim();\n            value = value.Substring(endIndex + 1);\n          } else {\n            // Last char was a separator, which is invalid.\n            break;\n          }\n\n          if (!ignoreCase) {\n            switch (subValue) {\n            case nameof(TestEnum.Test1):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test1;\n              break;\n\n            case nameof(TestEnum.Test2):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test2;\n              break;\n\n            case nameof(TestEnum.Test4):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test4;\n              break;\n\n            case nameof(TestEnum.Test5):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test5;\n              break;\n\n            case nameof(TestEnum.Test6):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test6;\n              break;\n\n            case nameof(TestEnum.Test7):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test7;\n              break;\n\n            case nameof(TestEnum.Test_1):\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test_1;\n              break;\n\n            }\n          } else {\n            if (subValue.Equals(\"Test1\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test1;\n            }\n            if (subValue.Equals(\"Test2\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test2;\n            }\n            if (subValue.Equals(\"Test4\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test4;\n            }\n            if (subValue.Equals(\"Test5\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test5;\n            }\n            if (subValue.Equals(\"Test6\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test6;\n            }\n            if (subValue.Equals(\"Test7\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test7;\n            }\n            if (subValue.Equals(\"Test_1\", StringComparison.OrdinalIgnoreCase)) {\n              parsed = true;\n              localResult |= (Int32) TestEnum.Test_1;\n            }\n\n          }\n\n          if (!parsed)\n            break;\n        }\n\n      successful = true;\n\n      if (!parsed) {\n        successful = false;\n\n        if (throwOnFailure)\n          throw new ArgumentException($\"Could not convert the given value `{originalValue}`.\", nameof(value));\n      }\n\n      return (TestEnum) localResult;\n    }\n\n  }\n}\n\n#nullable restore\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowberry-software%2FEnumsEnhanced","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnowberry-software%2FEnumsEnhanced","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowberry-software%2FEnumsEnhanced/lists"}