using System.Globalization; namespace MeterVault.App.Localization; /// /// UI-language plumbing around , the strongly-typed accessor MSBuild generates /// from Strings.resx (see the EmbeddedResource block in the project file). /// /// /// /// The neutral resource is English and every other language ships as a satellite assembly, so an /// Accept-Language we don't translate degrades to English rather than to raw resource keys. /// Strings are referenced as compiled properties (S.Common_Save), not string lookups, so a /// key that no longer exists is a build error instead of a mystery label at runtime. /// /// /// Number and date formatting follows and the UI /// language follows ; the request-localization middleware /// sets both from the same choice, so the two never disagree. /// /// public static class Loc { /// Cultures the UI ships translations for. The first entry is the neutral fallback. public static IReadOnlyList SupportedCultures { get; } = ["en", "de"]; /// Formats a resource carrying {0}-style placeholders in the request's culture. public static string F(string format, params object?[] args) => string.Format(CultureInfo.CurrentCulture, format, args); /// /// Maps a requested language onto one we actually ship, matching on the two-letter tag so /// de-AT and de-CH get German instead of falling through to English. /// /// true when the request named a language we translate. public static bool TryResolve(string? requested, out string resolved) { resolved = SupportedCultures[0]; if (string.IsNullOrWhiteSpace(requested)) { return false; } var trimmed = requested.Trim(); var separator = trimmed.IndexOfAny(['-', '_']); var language = separator < 0 ? trimmed : trimmed[..separator]; foreach (var supported in SupportedCultures) { if (string.Equals(supported, language, StringComparison.OrdinalIgnoreCase)) { resolved = supported; return true; } } return false; } /// The display name of a supported culture, written in that language ("Deutsch", "English"). public static string DisplayName(string culture) => CultureInfo.GetCultureInfo(culture).NativeName; }