elixir-cldr / cldr_territories

Territory formatting functions for the Common Locale Data Repository (CLDR) package https://github.com/elixir-cldr/cldr
Other
23 stars 11 forks source link

Cldr.Territory.from_subdivision_code/2 should resolve aliases #33

Closed kipcole9 closed 1 year ago

kipcole9 commented 1 year ago

Copied from https://github.com/elixir-cldr/cldr/issues/209

Summary

When resolving the names associated with a subdivision, such as uspr, no name is returned even though it's a valid subdivision code. This is because uspr is an alias to the territory PR (Puerto Rico). It can also be the case that a subdivision is deprecated and therefore it is also aliased.

CLDR provides a database of aliases that is returned by Cldr.Config.aliases/0 which is a map, including the key :subdivision under which the subdivision aliases are stored.

This issue is to request that Cldr.Territory.from_subdivision_code/2 resolve aliases to either base subdivision or, in situations like the above, territory code.

Suggested approach

  1. Add Cldr.Territory.subdivision_aliases/0 which encapsulates the alias information. This information can be obtained at compile time from Cldr.Config.aliases[:subdivision]
  2. Which resolving a subdivision, recursively resolve the subdivision name through the aliases until no more aliases are found.
  3. If the result is a territory code (an uncased atom) then use that territory code. If the result is a string its a subdivision code, use the subdivision code.
  4. Resolve the territory name - subdivision or territory

Subdivision alias data

Today, Cldr.Config.aliases/0 will return subdivision aliases as strings no matter whether they are territories or subdivisions. By definition, territories should be of the type t:Cldr.Locale.territory_code/0 which is an uncased atom. The following code is suggested to overcome this bug (which will be fixed in the next ex_cldr release:

  @subdivision_aliases Cldr.Config.aliases()
    |> Map.fetch!(:subdivision)
    |> Enum.map(fn 
      {k, v} when is_binary(v) ->
        if String.length(v) == 2, do: {k, String.to_atom(v)}, else: {k, v}
      other -> other
    end)
    |> Map.new()

  def subdivision_aliases do
    @subdivision_aliases
  end
Schultzer commented 1 year ago

@tomciopp I've opened a PR that resolves the subdivision aliases. I would be pleased if you could try out the branch and see if it works for you.

{:ex_cldr_territories, github: "Schultzer/cldr_territories",  branch: "resolve-subdivision-aliases"}
{:ex_cldr_territories, github: "Schultzer/cldr_territories",  ref: "809349580526ed8eff1d6e4a557fdf4110d20c7d"}
tomciopp commented 1 year ago

@Schultzer Yes, this code now works as expected.

Schultzer commented 1 year ago

@Schultzer Yes, this code now works as expected.

Thanks, I've pushed the changes to master.