From d95d55e6b86303286b719e97983289b24b7599d2 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Wed, 3 Jun 2026 11:39:20 +0200 Subject: [PATCH] feat(i18n): add CultureResolver for OS-culture mapping --- src/ClaudeDo.Localization/CultureResolver.cs | 16 ++++++++++++++++ .../CultureResolverTests.cs | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/ClaudeDo.Localization/CultureResolver.cs create mode 100644 tests/ClaudeDo.Localization.Tests/CultureResolverTests.cs diff --git a/src/ClaudeDo.Localization/CultureResolver.cs b/src/ClaudeDo.Localization/CultureResolver.cs new file mode 100644 index 0000000..95aa6f5 --- /dev/null +++ b/src/ClaudeDo.Localization/CultureResolver.cs @@ -0,0 +1,16 @@ +namespace ClaudeDo.Localization; + +public static class CultureResolver +{ + public static string Resolve(string cultureName, IReadOnlyCollection available, string fallback = "en") + { + if (string.IsNullOrWhiteSpace(cultureName)) return fallback; + + var exact = available.FirstOrDefault(c => string.Equals(c, cultureName, StringComparison.OrdinalIgnoreCase)); + if (exact is not null) return exact; + + var primary = cultureName.Split('-')[0]; + var byPrimary = available.FirstOrDefault(c => string.Equals(c, primary, StringComparison.OrdinalIgnoreCase)); + return byPrimary ?? fallback; + } +} diff --git a/tests/ClaudeDo.Localization.Tests/CultureResolverTests.cs b/tests/ClaudeDo.Localization.Tests/CultureResolverTests.cs new file mode 100644 index 0000000..496de3e --- /dev/null +++ b/tests/ClaudeDo.Localization.Tests/CultureResolverTests.cs @@ -0,0 +1,19 @@ +using ClaudeDo.Localization; + +namespace ClaudeDo.Localization.Tests; + +public class CultureResolverTests +{ + private static readonly string[] Codes = { "en", "de" }; + + [Theory] + [InlineData("de-DE", "de")] + [InlineData("de", "de")] + [InlineData("en-US", "en")] + [InlineData("fr-FR", "en")] + [InlineData("", "en")] + public void Resolve_maps_culture_to_available_code(string culture, string expected) + { + Assert.Equal(expected, CultureResolver.Resolve(culture, Codes, fallback: "en")); + } +}