// MIT License
//
//Copyright (c) 2018 Brett Russell
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.


use std::fmt::{self, Display};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::{self, Visitor};
use thiserror::Error;

/// Two-character uppercase ISO 3166-1 strings for each country
pub mod alpha2;
/// Three-character uppercase ISO 3166-1 strings for each country
pub mod alpha3;
/// English short name ISO 3166-1 strings for each country
pub mod full;
/// Unsigned ISO 3166-1 integer IDs for each country
pub mod numeric;

mod sorted_arrays;

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
/// An enumeration of all ISO-3166-1 country codes
pub enum CountryCode {
    /// Afghanistan
    AFG,
    /// Åland Islands
    ALA,
    /// Albania
    ALB,
    /// Algeria
    DZA,
    /// American Samoa
    ASM,
    /// Andorra
    AND,
    /// Angola
    AGO,
    /// Anguilla
    AIA,
    /// Antarctica
    ATA,
    /// Antigua and Barbuda
    ATG,
    /// Argentina
    ARG,
    /// Armenia
    ARM,
    /// Aruba
    ABW,
    /// Australia
    AUS,
    /// Austria
    AUT,
    /// Azerbaijan
    AZE,
    /// Bahamas
    BHS,
    /// Bahrain
    BHR,
    /// Bangladesh
    BGD,
    /// Barbados
    BRB,
    /// Belarus
    BLR,
    /// Belgium
    BEL,
    /// Belize
    BLZ,
    /// Benin
    BEN,
    /// Bermuda
    BMU,
    /// Bhutan
    BTN,
    /// Bolivia (Plurinational State of)
    BOL,
    /// Bonaire, Sint Eustatius and Saba
    BES,
    /// Bosnia and Herzegovina
    BIH,
    /// Botswana
    BWA,
    /// Bouvet Island
    BVT,
    /// Brazil
    BRA,
    /// British Indian Ocean Territory
    IOT,
    /// Brunei Darussalam
    BRN,
    /// Bulgaria
    BGR,
    /// Burkina Faso
    BFA,
    /// Burundi
    BDI,
    /// Cabo Verde
    CPV,
    /// Cambodia
    KHM,
    /// Cameroon
    CMR,
    /// Canada
    CAN,
    /// Cayman Islands
    CYM,
    /// Central African Republic
    CAF,
    /// Chad
    TCD,
    /// Chile
    CHL,
    /// China
    CHN,
    /// Christmas Island
    CXR,
    /// Cocos (Keeling) Islands
    CCK,
    /// Colombia
    COL,
    /// Comoros
    COM,
    /// Congo
    COG,
    /// Congo (Democratic Republic of the)
    COD,
    /// Cook Islands
    COK,
    /// Costa Rica
    CRI,
    /// Côte d'Ivoire
    CIV,
    /// Croatia
    HRV,
    /// Cuba
    CUB,
    /// Curaçao
    CUW,
    /// Cyprus
    CYP,
    /// Czechia
    CZE,
    /// Denmark
    DNK,
    /// Djibouti
    DJI,
    /// Dominica
    DMA,
    /// Dominican Republic
    DOM,
    /// Ecuador
    ECU,
    /// Egypt
    EGY,
    /// El Salvador
    SLV,
    /// Equatorial Guinea
    GNQ,
    /// Eritrea
    ERI,
    /// Estonia
    EST,
    /// Ethiopia
    ETH,
    /// Falkland Islands (Malvinas)
    FLK,
    /// Faroe Islands
    FRO,
    /// Fiji
    FJI,
    /// Finland
    FIN,
    /// France
    FRA,
    /// French Guiana
    GUF,
    /// French Polynesia
    PYF,
    /// French Southern Territories
    ATF,
    /// Gabon
    GAB,
    /// Gambia
    GMB,
    /// Georgia
    GEO,
    /// Germany
    DEU,
    /// Ghana
    GHA,
    /// Gibraltar
    GIB,
    /// Greece
    GRC,
    /// Greenland
    GRL,
    /// Grenada
    GRD,
    /// Guadeloupe
    GLP,
    /// Guam
    GUM,
    /// Guatemala
    GTM,
    /// Guernsey
    GGY,
    /// Guinea
    GIN,
    /// Guinea-Bissau
    GNB,
    /// Guyana
    GUY,
    /// Haiti
    HTI,
    /// Heard Island and McDonald Islands
    HMD,
    /// Holy See
    VAT,
    /// Honduras
    HND,
    /// Hong Kong
    HKG,
    /// Hungary
    HUN,
    /// Iceland
    ISL,
    /// India
    IND,
    /// Indonesia
    IDN,
    /// Iran (Islamic Republic of)
    IRN,
    /// Iraq
    IRQ,
    /// Ireland
    IRL,
    /// Isle of Man
    IMN,
    /// Israel
    ISR,
    /// Italy
    ITA,
    /// Jamaica
    JAM,
    /// Japan
    JPN,
    /// Jersey
    JEY,
    /// Jordan
    JOR,
    /// Kazakhstan
    KAZ,
    /// Kenya
    KEN,
    /// Kiribati
    KIR,
    /// Korea (Democratic People's Republic of)
    PRK,
    /// Korea (Republic of)
    KOR,
    /// Kuwait
    KWT,
    /// Kyrgyzstan
    KGZ,
    /// Lao People's Democratic Republic
    LAO,
    /// Latvia
    LVA,
    /// Lebanon
    LBN,
    /// Lesotho
    LSO,
    /// Liberia
    LBR,
    /// Libya
    LBY,
    /// Liechtenstein
    LIE,
    /// Lithuania
    LTU,
    /// Luxembourg
    LUX,
    /// Macao
    MAC,
    /// Macedonia (the former Yugoslav Republic of)
    MKD,
    /// Madagascar
    MDG,
    /// Malawi
    MWI,
    /// Malaysia
    MYS,
    /// Maldives
    MDV,
    /// Mali
    MLI,
    /// Malta
    MLT,
    /// Marshall Islands
    MHL,
    /// Martinique
    MTQ,
    /// Mauritania
    MRT,
    /// Mauritius
    MUS,
    /// Mayotte
    MYT,
    /// Mexico
    MEX,
    /// Micronesia (Federated States of)
    FSM,
    /// Moldova (Republic of)
    MDA,
    /// Monaco
    MCO,
    /// Mongolia
    MNG,
    /// Montenegro
    MNE,
    /// Montserrat
    MSR,
    /// Morocco
    MAR,
    /// Mozambique
    MOZ,
    /// Myanmar
    MMR,
    /// Namibia
    NAM,
    /// Nauru
    NRU,
    /// Nepal
    NPL,
    /// Netherlands
    NLD,
    /// New Caledonia
    NCL,
    /// New Zealand
    NZL,
    /// Nicaragua
    NIC,
    /// Niger
    NER,
    /// Nigeria
    NGA,
    /// Niue
    NIU,
    /// Norfolk Island
    NFK,
    /// Northern Mariana Islands
    MNP,
    /// Norway
    NOR,
    /// Oman
    OMN,
    /// Pakistan
    PAK,
    /// Palau
    PLW,
    /// Palestine, State of
    PSE,
    /// Panama
    PAN,
    /// Papua New Guinea
    PNG,
    /// Paraguay
    PRY,
    /// Peru
    PER,
    /// Philippines
    PHL,
    /// Pitcairn
    PCN,
    /// Poland
    POL,
    /// Portugal
    PRT,
    /// Puerto Rico
    PRI,
    /// Qatar
    QAT,
    /// Réunion
    REU,
    /// Romania
    ROU,
    /// Russian Federation
    RUS,
    /// Rwanda
    RWA,
    /// Saint Barthélemy
    BLM,
    /// Saint Helena, Ascension and Tristan da Cunha
    SHN,
    /// Saint Kitts and Nevis
    KNA,
    /// Saint Lucia
    LCA,
    /// Saint Martin (French part)
    MAF,
    /// Saint Pierre and Miquelon
    SPM,
    /// Saint Vincent and the Grenadines
    VCT,
    /// Samoa
    WSM,
    /// San Marino
    SMR,
    /// Sao Tome and Principe
    STP,
    /// Saudi Arabia
    SAU,
    /// Senegal
    SEN,
    /// Serbia
    SRB,
    /// Seychelles
    SYC,
    /// Sierra Leone
    SLE,
    /// Singapore
    SGP,
    /// Sint Maarten (Dutch part)
    SXM,
    /// Slovakia
    SVK,
    /// Slovenia
    SVN,
    /// Solomon Islands
    SLB,
    /// Somalia
    SOM,
    /// South Africa
    ZAF,
    /// South Georgia and the South Sandwich Islands
    SGS,
    /// South Sudan
    SSD,
    /// Spain
    ESP,
    /// Sri Lanka
    LKA,
    /// Sudan
    SDN,
    /// Suriname
    SUR,
    /// Svalbard and Jan Mayen
    SJM,
    /// Swaziland
    SWZ,
    /// Sweden
    SWE,
    /// Switzerland
    CHE,
    /// Syrian Arab Republic
    SYR,
    /// Taiwan, Province of China
    TWN,
    /// Tajikistan
    TJK,
    /// Tanzania, United Republic of
    TZA,
    /// Thailand
    THA,
    /// Timor-Leste
    TLS,
    /// Togo
    TGO,
    /// Tokelau
    TKL,
    /// Tonga
    TON,
    /// Trinidad and Tobago
    TTO,
    /// Tunisia
    TUN,
    /// Turkey
    TUR,
    /// Turkmenistan
    TKM,
    /// Turks and Caicos Islands
    TCA,
    /// Tuvalu
    TUV,
    /// Uganda
    UGA,
    /// Ukraine
    UKR,
    /// United Arab Emirates
    ARE,
    /// United Kingdom of Great Britain and Northern Ireland
    GBR,
    /// United States of America
    USA,
    /// United States Minor Outlying Islands
    UMI,
    /// Uruguay
    URY,
    /// Uzbekistan
    UZB,
    /// Vanuatu
    VUT,
    /// Venezuela (Bolivarian Republic of)
    VEN,
    /// Viet Nam
    VNM,
    /// Virgin Islands (British)
    VGB,
    /// Virgin Islands (U.S.)
    VIR,
    /// Wallis and Futuna
    WLF,
    /// Western Sahara
    ESH,
    /// Yemen
    YEM,
    /// Zambia
    ZMB,
    /// Zimbabwe
    ZWE,
}

/// Errors that might arise when converting raw data into CountryCode
#[derive(Debug, Error, PartialEq)]
pub enum CountryCodeParseErr {
    #[error("invalid alpha-2 country code string: {}", unknown)]
    InvalidAlpha2 { unknown: String },
    #[error("invalid alpha-3 country code string: {}", unknown)]
    InvalidAlpha3 { unknown: String },
    #[error("invalid ID (integer) country code: {}", unknown)]
    InvalidID { unknown: u32 },
}

const NUM_COUNTRY_CODES: usize = 249;

impl CountryCode {
    /// Returns the ISO 3166-1 English short name
    pub fn name(&self) -> &'static str {
        use self::CountryCode::*;
        use full::*;
        match *self {
            AFG => ISO_FULL_AFG,
            ALA => ISO_FULL_ALA,
            ALB => ISO_FULL_ALB,
            DZA => ISO_FULL_DZA,
            ASM => ISO_FULL_ASM,
            AND => ISO_FULL_AND,
            AGO => ISO_FULL_AGO,
            AIA => ISO_FULL_AIA,
            ATA => ISO_FULL_ATA,
            ATG => ISO_FULL_ATG,
            ARG => ISO_FULL_ARG,
            ARM => ISO_FULL_ARM,
            ABW => ISO_FULL_ABW,
            AUS => ISO_FULL_AUS,
            AUT => ISO_FULL_AUT,
            AZE => ISO_FULL_AZE,
            BHS => ISO_FULL_BHS,
            BHR => ISO_FULL_BHR,
            BGD => ISO_FULL_BGD,
            BRB => ISO_FULL_BRB,
            BLR => ISO_FULL_BLR,
            BEL => ISO_FULL_BEL,
            BLZ => ISO_FULL_BLZ,
            BEN => ISO_FULL_BEN,
            BMU => ISO_FULL_BMU,
            BTN => ISO_FULL_BTN,
            BOL => ISO_FULL_BOL,
            BES => ISO_FULL_BES,
            BIH => ISO_FULL_BIH,
            BWA => ISO_FULL_BWA,
            BVT => ISO_FULL_BVT,
            BRA => ISO_FULL_BRA,
            IOT => ISO_FULL_IOT,
            BRN => ISO_FULL_BRN,
            BGR => ISO_FULL_BGR,
            BFA => ISO_FULL_BFA,
            BDI => ISO_FULL_BDI,
            CPV => ISO_FULL_CPV,
            KHM => ISO_FULL_KHM,
            CMR => ISO_FULL_CMR,
            CAN => ISO_FULL_CAN,
            CYM => ISO_FULL_CYM,
            CAF => ISO_FULL_CAF,
            TCD => ISO_FULL_TCD,
            CHL => ISO_FULL_CHL,
            CHN => ISO_FULL_CHN,
            CXR => ISO_FULL_CXR,
            CCK => ISO_FULL_CCK,
            COL => ISO_FULL_COL,
            COM => ISO_FULL_COM,
            COG => ISO_FULL_COG,
            COD => ISO_FULL_COD,
            COK => ISO_FULL_COK,
            CRI => ISO_FULL_CRI,
            CIV => ISO_FULL_CIV,
            HRV => ISO_FULL_HRV,
            CUB => ISO_FULL_CUB,
            CUW => ISO_FULL_CUW,
            CYP => ISO_FULL_CYP,
            CZE => ISO_FULL_CZE,
            DNK => ISO_FULL_DNK,
            DJI => ISO_FULL_DJI,
            DMA => ISO_FULL_DMA,
            DOM => ISO_FULL_DOM,
            ECU => ISO_FULL_ECU,
            EGY => ISO_FULL_EGY,
            SLV => ISO_FULL_SLV,
            GNQ => ISO_FULL_GNQ,
            ERI => ISO_FULL_ERI,
            EST => ISO_FULL_EST,
            ETH => ISO_FULL_ETH,
            FLK => ISO_FULL_FLK,
            FRO => ISO_FULL_FRO,
            FJI => ISO_FULL_FJI,
            FIN => ISO_FULL_FIN,
            FRA => ISO_FULL_FRA,
            GUF => ISO_FULL_GUF,
            PYF => ISO_FULL_PYF,
            ATF => ISO_FULL_ATF,
            GAB => ISO_FULL_GAB,
            GMB => ISO_FULL_GMB,
            GEO => ISO_FULL_GEO,
            DEU => ISO_FULL_DEU,
            GHA => ISO_FULL_GHA,
            GIB => ISO_FULL_GIB,
            GRC => ISO_FULL_GRC,
            GRL => ISO_FULL_GRL,
            GRD => ISO_FULL_GRD,
            GLP => ISO_FULL_GLP,
            GUM => ISO_FULL_GUM,
            GTM => ISO_FULL_GTM,
            GGY => ISO_FULL_GGY,
            GIN => ISO_FULL_GIN,
            GNB => ISO_FULL_GNB,
            GUY => ISO_FULL_GUY,
            HTI => ISO_FULL_HTI,
            HMD => ISO_FULL_HMD,
            VAT => ISO_FULL_VAT,
            HND => ISO_FULL_HND,
            HKG => ISO_FULL_HKG,
            HUN => ISO_FULL_HUN,
            ISL => ISO_FULL_ISL,
            IND => ISO_FULL_IND,
            IDN => ISO_FULL_IDN,
            IRN => ISO_FULL_IRN,
            IRQ => ISO_FULL_IRQ,
            IRL => ISO_FULL_IRL,
            IMN => ISO_FULL_IMN,
            ISR => ISO_FULL_ISR,
            ITA => ISO_FULL_ITA,
            JAM => ISO_FULL_JAM,
            JPN => ISO_FULL_JPN,
            JEY => ISO_FULL_JEY,
            JOR => ISO_FULL_JOR,
            KAZ => ISO_FULL_KAZ,
            KEN => ISO_FULL_KEN,
            KIR => ISO_FULL_KIR,
            PRK => ISO_FULL_PRK,
            KOR => ISO_FULL_KOR,
            KWT => ISO_FULL_KWT,
            KGZ => ISO_FULL_KGZ,
            LAO => ISO_FULL_LAO,
            LVA => ISO_FULL_LVA,
            LBN => ISO_FULL_LBN,
            LSO => ISO_FULL_LSO,
            LBR => ISO_FULL_LBR,
            LBY => ISO_FULL_LBY,
            LIE => ISO_FULL_LIE,
            LTU => ISO_FULL_LTU,
            LUX => ISO_FULL_LUX,
            MAC => ISO_FULL_MAC,
            MKD => ISO_FULL_MKD,
            MDG => ISO_FULL_MDG,
            MWI => ISO_FULL_MWI,
            MYS => ISO_FULL_MYS,
            MDV => ISO_FULL_MDV,
            MLI => ISO_FULL_MLI,
            MLT => ISO_FULL_MLT,
            MHL => ISO_FULL_MHL,
            MTQ => ISO_FULL_MTQ,
            MRT => ISO_FULL_MRT,
            MUS => ISO_FULL_MUS,
            MYT => ISO_FULL_MYT,
            MEX => ISO_FULL_MEX,
            FSM => ISO_FULL_FSM,
            MDA => ISO_FULL_MDA,
            MCO => ISO_FULL_MCO,
            MNG => ISO_FULL_MNG,
            MNE => ISO_FULL_MNE,
            MSR => ISO_FULL_MSR,
            MAR => ISO_FULL_MAR,
            MOZ => ISO_FULL_MOZ,
            MMR => ISO_FULL_MMR,
            NAM => ISO_FULL_NAM,
            NRU => ISO_FULL_NRU,
            NPL => ISO_FULL_NPL,
            NLD => ISO_FULL_NLD,
            NCL => ISO_FULL_NCL,
            NZL => ISO_FULL_NZL,
            NIC => ISO_FULL_NIC,
            NER => ISO_FULL_NER,
            NGA => ISO_FULL_NGA,
            NIU => ISO_FULL_NIU,
            NFK => ISO_FULL_NFK,
            MNP => ISO_FULL_MNP,
            NOR => ISO_FULL_NOR,
            OMN => ISO_FULL_OMN,
            PAK => ISO_FULL_PAK,
            PLW => ISO_FULL_PLW,
            PSE => ISO_FULL_PSE,
            PAN => ISO_FULL_PAN,
            PNG => ISO_FULL_PNG,
            PRY => ISO_FULL_PRY,
            PER => ISO_FULL_PER,
            PHL => ISO_FULL_PHL,
            PCN => ISO_FULL_PCN,
            POL => ISO_FULL_POL,
            PRT => ISO_FULL_PRT,
            PRI => ISO_FULL_PRI,
            QAT => ISO_FULL_QAT,
            REU => ISO_FULL_REU,
            ROU => ISO_FULL_ROU,
            RUS => ISO_FULL_RUS,
            RWA => ISO_FULL_RWA,
            BLM => ISO_FULL_BLM,
            SHN => ISO_FULL_SHN,
            KNA => ISO_FULL_KNA,
            LCA => ISO_FULL_LCA,
            MAF => ISO_FULL_MAF,
            SPM => ISO_FULL_SPM,
            VCT => ISO_FULL_VCT,
            WSM => ISO_FULL_WSM,
            SMR => ISO_FULL_SMR,
            STP => ISO_FULL_STP,
            SAU => ISO_FULL_SAU,
            SEN => ISO_FULL_SEN,
            SRB => ISO_FULL_SRB,
            SYC => ISO_FULL_SYC,
            SLE => ISO_FULL_SLE,
            SGP => ISO_FULL_SGP,
            SXM => ISO_FULL_SXM,
            SVK => ISO_FULL_SVK,
            SVN => ISO_FULL_SVN,
            SLB => ISO_FULL_SLB,
            SOM => ISO_FULL_SOM,
            ZAF => ISO_FULL_ZAF,
            SGS => ISO_FULL_SGS,
            SSD => ISO_FULL_SSD,
            ESP => ISO_FULL_ESP,
            LKA => ISO_FULL_LKA,
            SDN => ISO_FULL_SDN,
            SUR => ISO_FULL_SUR,
            SJM => ISO_FULL_SJM,
            SWZ => ISO_FULL_SWZ,
            SWE => ISO_FULL_SWE,
            CHE => ISO_FULL_CHE,
            SYR => ISO_FULL_SYR,
            TWN => ISO_FULL_TWN,
            TJK => ISO_FULL_TJK,
            TZA => ISO_FULL_TZA,
            THA => ISO_FULL_THA,
            TLS => ISO_FULL_TLS,
            TGO => ISO_FULL_TGO,
            TKL => ISO_FULL_TKL,
            TON => ISO_FULL_TON,
            TTO => ISO_FULL_TTO,
            TUN => ISO_FULL_TUN,
            TUR => ISO_FULL_TUR,
            TKM => ISO_FULL_TKM,
            TCA => ISO_FULL_TCA,
            TUV => ISO_FULL_TUV,
            UGA => ISO_FULL_UGA,
            UKR => ISO_FULL_UKR,
            ARE => ISO_FULL_ARE,
            GBR => ISO_FULL_GBR,
            USA => ISO_FULL_USA,
            UMI => ISO_FULL_UMI,
            URY => ISO_FULL_URY,
            UZB => ISO_FULL_UZB,
            VUT => ISO_FULL_VUT,
            VEN => ISO_FULL_VEN,
            VNM => ISO_FULL_VNM,
            VGB => ISO_FULL_VGB,
            VIR => ISO_FULL_VIR,
            WLF => ISO_FULL_WLF,
            ESH => ISO_FULL_ESH,
            YEM => ISO_FULL_YEM,
            ZMB => ISO_FULL_ZMB,
            ZWE => ISO_FULL_ZWE,
        }
    }

    /// Returns the ISO 3166-1 numeric ID
    pub fn numeric_id(&self) -> u32 {
        use self::CountryCode::*;
        use numeric::*;
        match *self {
            AFG => ISO_NUM_AFG,
            ALA => ISO_NUM_ALA,
            ALB => ISO_NUM_ALB,
            DZA => ISO_NUM_DZA,
            ASM => ISO_NUM_ASM,
            AND => ISO_NUM_AND,
            AGO => ISO_NUM_AGO,
            AIA => ISO_NUM_AIA,
            ATA => ISO_NUM_ATA,
            ATG => ISO_NUM_ATG,
            ARG => ISO_NUM_ARG,
            ARM => ISO_NUM_ARM,
            ABW => ISO_NUM_ABW,
            AUS => ISO_NUM_AUS,
            AUT => ISO_NUM_AUT,
            AZE => ISO_NUM_AZE,
            BHS => ISO_NUM_BHS,
            BHR => ISO_NUM_BHR,
            BGD => ISO_NUM_BGD,
            BRB => ISO_NUM_BRB,
            BLR => ISO_NUM_BLR,
            BEL => ISO_NUM_BEL,
            BLZ => ISO_NUM_BLZ,
            BEN => ISO_NUM_BEN,
            BMU => ISO_NUM_BMU,
            BTN => ISO_NUM_BTN,
            BOL => ISO_NUM_BOL,
            BES => ISO_NUM_BES,
            BIH => ISO_NUM_BIH,
            BWA => ISO_NUM_BWA,
            BVT => ISO_NUM_BVT,
            BRA => ISO_NUM_BRA,
            IOT => ISO_NUM_IOT,
            BRN => ISO_NUM_BRN,
            BGR => ISO_NUM_BGR,
            BFA => ISO_NUM_BFA,
            BDI => ISO_NUM_BDI,
            CPV => ISO_NUM_CPV,
            KHM => ISO_NUM_KHM,
            CMR => ISO_NUM_CMR,
            CAN => ISO_NUM_CAN,
            CYM => ISO_NUM_CYM,
            CAF => ISO_NUM_CAF,
            TCD => ISO_NUM_TCD,
            CHL => ISO_NUM_CHL,
            CHN => ISO_NUM_CHN,
            CXR => ISO_NUM_CXR,
            CCK => ISO_NUM_CCK,
            COL => ISO_NUM_COL,
            COM => ISO_NUM_COM,
            COG => ISO_NUM_COG,
            COD => ISO_NUM_COD,
            COK => ISO_NUM_COK,
            CRI => ISO_NUM_CRI,
            CIV => ISO_NUM_CIV,
            HRV => ISO_NUM_HRV,
            CUB => ISO_NUM_CUB,
            CUW => ISO_NUM_CUW,
            CYP => ISO_NUM_CYP,
            CZE => ISO_NUM_CZE,
            DNK => ISO_NUM_DNK,
            DJI => ISO_NUM_DJI,
            DMA => ISO_NUM_DMA,
            DOM => ISO_NUM_DOM,
            ECU => ISO_NUM_ECU,
            EGY => ISO_NUM_EGY,
            SLV => ISO_NUM_SLV,
            GNQ => ISO_NUM_GNQ,
            ERI => ISO_NUM_ERI,
            EST => ISO_NUM_EST,
            ETH => ISO_NUM_ETH,
            FLK => ISO_NUM_FLK,
            FRO => ISO_NUM_FRO,
            FJI => ISO_NUM_FJI,
            FIN => ISO_NUM_FIN,
            FRA => ISO_NUM_FRA,
            GUF => ISO_NUM_GUF,
            PYF => ISO_NUM_PYF,
            ATF => ISO_NUM_ATF,
            GAB => ISO_NUM_GAB,
            GMB => ISO_NUM_GMB,
            GEO => ISO_NUM_GEO,
            DEU => ISO_NUM_DEU,
            GHA => ISO_NUM_GHA,
            GIB => ISO_NUM_GIB,
            GRC => ISO_NUM_GRC,
            GRL => ISO_NUM_GRL,
            GRD => ISO_NUM_GRD,
            GLP => ISO_NUM_GLP,
            GUM => ISO_NUM_GUM,
            GTM => ISO_NUM_GTM,
            GGY => ISO_NUM_GGY,
            GIN => ISO_NUM_GIN,
            GNB => ISO_NUM_GNB,
            GUY => ISO_NUM_GUY,
            HTI => ISO_NUM_HTI,
            HMD => ISO_NUM_HMD,
            VAT => ISO_NUM_VAT,
            HND => ISO_NUM_HND,
            HKG => ISO_NUM_HKG,
            HUN => ISO_NUM_HUN,
            ISL => ISO_NUM_ISL,
            IND => ISO_NUM_IND,
            IDN => ISO_NUM_IDN,
            IRN => ISO_NUM_IRN,
            IRQ => ISO_NUM_IRQ,
            IRL => ISO_NUM_IRL,
            IMN => ISO_NUM_IMN,
            ISR => ISO_NUM_ISR,
            ITA => ISO_NUM_ITA,
            JAM => ISO_NUM_JAM,
            JPN => ISO_NUM_JPN,
            JEY => ISO_NUM_JEY,
            JOR => ISO_NUM_JOR,
            KAZ => ISO_NUM_KAZ,
            KEN => ISO_NUM_KEN,
            KIR => ISO_NUM_KIR,
            PRK => ISO_NUM_PRK,
            KOR => ISO_NUM_KOR,
            KWT => ISO_NUM_KWT,
            KGZ => ISO_NUM_KGZ,
            LAO => ISO_NUM_LAO,
            LVA => ISO_NUM_LVA,
            LBN => ISO_NUM_LBN,
            LSO => ISO_NUM_LSO,
            LBR => ISO_NUM_LBR,
            LBY => ISO_NUM_LBY,
            LIE => ISO_NUM_LIE,
            LTU => ISO_NUM_LTU,
            LUX => ISO_NUM_LUX,
            MAC => ISO_NUM_MAC,
            MKD => ISO_NUM_MKD,
            MDG => ISO_NUM_MDG,
            MWI => ISO_NUM_MWI,
            MYS => ISO_NUM_MYS,
            MDV => ISO_NUM_MDV,
            MLI => ISO_NUM_MLI,
            MLT => ISO_NUM_MLT,
            MHL => ISO_NUM_MHL,
            MTQ => ISO_NUM_MTQ,
            MRT => ISO_NUM_MRT,
            MUS => ISO_NUM_MUS,
            MYT => ISO_NUM_MYT,
            MEX => ISO_NUM_MEX,
            FSM => ISO_NUM_FSM,
            MDA => ISO_NUM_MDA,
            MCO => ISO_NUM_MCO,
            MNG => ISO_NUM_MNG,
            MNE => ISO_NUM_MNE,
            MSR => ISO_NUM_MSR,
            MAR => ISO_NUM_MAR,
            MOZ => ISO_NUM_MOZ,
            MMR => ISO_NUM_MMR,
            NAM => ISO_NUM_NAM,
            NRU => ISO_NUM_NRU,
            NPL => ISO_NUM_NPL,
            NLD => ISO_NUM_NLD,
            NCL => ISO_NUM_NCL,
            NZL => ISO_NUM_NZL,
            NIC => ISO_NUM_NIC,
            NER => ISO_NUM_NER,
            NGA => ISO_NUM_NGA,
            NIU => ISO_NUM_NIU,
            NFK => ISO_NUM_NFK,
            MNP => ISO_NUM_MNP,
            NOR => ISO_NUM_NOR,
            OMN => ISO_NUM_OMN,
            PAK => ISO_NUM_PAK,
            PLW => ISO_NUM_PLW,
            PSE => ISO_NUM_PSE,
            PAN => ISO_NUM_PAN,
            PNG => ISO_NUM_PNG,
            PRY => ISO_NUM_PRY,
            PER => ISO_NUM_PER,
            PHL => ISO_NUM_PHL,
            PCN => ISO_NUM_PCN,
            POL => ISO_NUM_POL,
            PRT => ISO_NUM_PRT,
            PRI => ISO_NUM_PRI,
            QAT => ISO_NUM_QAT,
            REU => ISO_NUM_REU,
            ROU => ISO_NUM_ROU,
            RUS => ISO_NUM_RUS,
            RWA => ISO_NUM_RWA,
            BLM => ISO_NUM_BLM,
            SHN => ISO_NUM_SHN,
            KNA => ISO_NUM_KNA,
            LCA => ISO_NUM_LCA,
            MAF => ISO_NUM_MAF,
            SPM => ISO_NUM_SPM,
            VCT => ISO_NUM_VCT,
            WSM => ISO_NUM_WSM,
            SMR => ISO_NUM_SMR,
            STP => ISO_NUM_STP,
            SAU => ISO_NUM_SAU,
            SEN => ISO_NUM_SEN,
            SRB => ISO_NUM_SRB,
            SYC => ISO_NUM_SYC,
            SLE => ISO_NUM_SLE,
            SGP => ISO_NUM_SGP,
            SXM => ISO_NUM_SXM,
            SVK => ISO_NUM_SVK,
            SVN => ISO_NUM_SVN,
            SLB => ISO_NUM_SLB,
            SOM => ISO_NUM_SOM,
            ZAF => ISO_NUM_ZAF,
            SGS => ISO_NUM_SGS,
            SSD => ISO_NUM_SSD,
            ESP => ISO_NUM_ESP,
            LKA => ISO_NUM_LKA,
            SDN => ISO_NUM_SDN,
            SUR => ISO_NUM_SUR,
            SJM => ISO_NUM_SJM,
            SWZ => ISO_NUM_SWZ,
            SWE => ISO_NUM_SWE,
            CHE => ISO_NUM_CHE,
            SYR => ISO_NUM_SYR,
            TWN => ISO_NUM_TWN,
            TJK => ISO_NUM_TJK,
            TZA => ISO_NUM_TZA,
            THA => ISO_NUM_THA,
            TLS => ISO_NUM_TLS,
            TGO => ISO_NUM_TGO,
            TKL => ISO_NUM_TKL,
            TON => ISO_NUM_TON,
            TTO => ISO_NUM_TTO,
            TUN => ISO_NUM_TUN,
            TUR => ISO_NUM_TUR,
            TKM => ISO_NUM_TKM,
            TCA => ISO_NUM_TCA,
            TUV => ISO_NUM_TUV,
            UGA => ISO_NUM_UGA,
            UKR => ISO_NUM_UKR,
            ARE => ISO_NUM_ARE,
            GBR => ISO_NUM_GBR,
            USA => ISO_NUM_USA,
            UMI => ISO_NUM_UMI,
            URY => ISO_NUM_URY,
            UZB => ISO_NUM_UZB,
            VUT => ISO_NUM_VUT,
            VEN => ISO_NUM_VEN,
            VNM => ISO_NUM_VNM,
            VGB => ISO_NUM_VGB,
            VIR => ISO_NUM_VIR,
            WLF => ISO_NUM_WLF,
            ESH => ISO_NUM_ESH,
            YEM => ISO_NUM_YEM,
            ZMB => ISO_NUM_ZMB,
            ZWE => ISO_NUM_ZWE,
        }
    }

    /// Returns the uppercase two-character ISO 3166-1 string
    pub fn alpha2(&self) -> &'static str {
        use self::CountryCode::*;
        use alpha2::*;
        match *self {
            AFG => ISO_A2_AFG,
            ALA => ISO_A2_ALA,
            ALB => ISO_A2_ALB,
            DZA => ISO_A2_DZA,
            ASM => ISO_A2_ASM,
            AND => ISO_A2_AND,
            AGO => ISO_A2_AGO,
            AIA => ISO_A2_AIA,
            ATA => ISO_A2_ATA,
            ATG => ISO_A2_ATG,
            ARG => ISO_A2_ARG,
            ARM => ISO_A2_ARM,
            ABW => ISO_A2_ABW,
            AUS => ISO_A2_AUS,
            AUT => ISO_A2_AUT,
            AZE => ISO_A2_AZE,
            BHS => ISO_A2_BHS,
            BHR => ISO_A2_BHR,
            BGD => ISO_A2_BGD,
            BRB => ISO_A2_BRB,
            BLR => ISO_A2_BLR,
            BEL => ISO_A2_BEL,
            BLZ => ISO_A2_BLZ,
            BEN => ISO_A2_BEN,
            BMU => ISO_A2_BMU,
            BTN => ISO_A2_BTN,
            BOL => ISO_A2_BOL,
            BES => ISO_A2_BES,
            BIH => ISO_A2_BIH,
            BWA => ISO_A2_BWA,
            BVT => ISO_A2_BVT,
            BRA => ISO_A2_BRA,
            IOT => ISO_A2_IOT,
            BRN => ISO_A2_BRN,
            BGR => ISO_A2_BGR,
            BFA => ISO_A2_BFA,
            BDI => ISO_A2_BDI,
            CPV => ISO_A2_CPV,
            KHM => ISO_A2_KHM,
            CMR => ISO_A2_CMR,
            CAN => ISO_A2_CAN,
            CYM => ISO_A2_CYM,
            CAF => ISO_A2_CAF,
            TCD => ISO_A2_TCD,
            CHL => ISO_A2_CHL,
            CHN => ISO_A2_CHN,
            CXR => ISO_A2_CXR,
            CCK => ISO_A2_CCK,
            COL => ISO_A2_COL,
            COM => ISO_A2_COM,
            COG => ISO_A2_COG,
            COD => ISO_A2_COD,
            COK => ISO_A2_COK,
            CRI => ISO_A2_CRI,
            CIV => ISO_A2_CIV,
            HRV => ISO_A2_HRV,
            CUB => ISO_A2_CUB,
            CUW => ISO_A2_CUW,
            CYP => ISO_A2_CYP,
            CZE => ISO_A2_CZE,
            DNK => ISO_A2_DNK,
            DJI => ISO_A2_DJI,
            DMA => ISO_A2_DMA,
            DOM => ISO_A2_DOM,
            ECU => ISO_A2_ECU,
            EGY => ISO_A2_EGY,
            SLV => ISO_A2_SLV,
            GNQ => ISO_A2_GNQ,
            ERI => ISO_A2_ERI,
            EST => ISO_A2_EST,
            ETH => ISO_A2_ETH,
            FLK => ISO_A2_FLK,
            FRO => ISO_A2_FRO,
            FJI => ISO_A2_FJI,
            FIN => ISO_A2_FIN,
            FRA => ISO_A2_FRA,
            GUF => ISO_A2_GUF,
            PYF => ISO_A2_PYF,
            ATF => ISO_A2_ATF,
            GAB => ISO_A2_GAB,
            GMB => ISO_A2_GMB,
            GEO => ISO_A2_GEO,
            DEU => ISO_A2_DEU,
            GHA => ISO_A2_GHA,
            GIB => ISO_A2_GIB,
            GRC => ISO_A2_GRC,
            GRL => ISO_A2_GRL,
            GRD => ISO_A2_GRD,
            GLP => ISO_A2_GLP,
            GUM => ISO_A2_GUM,
            GTM => ISO_A2_GTM,
            GGY => ISO_A2_GGY,
            GIN => ISO_A2_GIN,
            GNB => ISO_A2_GNB,
            GUY => ISO_A2_GUY,
            HTI => ISO_A2_HTI,
            HMD => ISO_A2_HMD,
            VAT => ISO_A2_VAT,
            HND => ISO_A2_HND,
            HKG => ISO_A2_HKG,
            HUN => ISO_A2_HUN,
            ISL => ISO_A2_ISL,
            IND => ISO_A2_IND,
            IDN => ISO_A2_IDN,
            IRN => ISO_A2_IRN,
            IRQ => ISO_A2_IRQ,
            IRL => ISO_A2_IRL,
            IMN => ISO_A2_IMN,
            ISR => ISO_A2_ISR,
            ITA => ISO_A2_ITA,
            JAM => ISO_A2_JAM,
            JPN => ISO_A2_JPN,
            JEY => ISO_A2_JEY,
            JOR => ISO_A2_JOR,
            KAZ => ISO_A2_KAZ,
            KEN => ISO_A2_KEN,
            KIR => ISO_A2_KIR,
            PRK => ISO_A2_PRK,
            KOR => ISO_A2_KOR,
            KWT => ISO_A2_KWT,
            KGZ => ISO_A2_KGZ,
            LAO => ISO_A2_LAO,
            LVA => ISO_A2_LVA,
            LBN => ISO_A2_LBN,
            LSO => ISO_A2_LSO,
            LBR => ISO_A2_LBR,
            LBY => ISO_A2_LBY,
            LIE => ISO_A2_LIE,
            LTU => ISO_A2_LTU,
            LUX => ISO_A2_LUX,
            MAC => ISO_A2_MAC,
            MKD => ISO_A2_MKD,
            MDG => ISO_A2_MDG,
            MWI => ISO_A2_MWI,
            MYS => ISO_A2_MYS,
            MDV => ISO_A2_MDV,
            MLI => ISO_A2_MLI,
            MLT => ISO_A2_MLT,
            MHL => ISO_A2_MHL,
            MTQ => ISO_A2_MTQ,
            MRT => ISO_A2_MRT,
            MUS => ISO_A2_MUS,
            MYT => ISO_A2_MYT,
            MEX => ISO_A2_MEX,
            FSM => ISO_A2_FSM,
            MDA => ISO_A2_MDA,
            MCO => ISO_A2_MCO,
            MNG => ISO_A2_MNG,
            MNE => ISO_A2_MNE,
            MSR => ISO_A2_MSR,
            MAR => ISO_A2_MAR,
            MOZ => ISO_A2_MOZ,
            MMR => ISO_A2_MMR,
            NAM => ISO_A2_NAM,
            NRU => ISO_A2_NRU,
            NPL => ISO_A2_NPL,
            NLD => ISO_A2_NLD,
            NCL => ISO_A2_NCL,
            NZL => ISO_A2_NZL,
            NIC => ISO_A2_NIC,
            NER => ISO_A2_NER,
            NGA => ISO_A2_NGA,
            NIU => ISO_A2_NIU,
            NFK => ISO_A2_NFK,
            MNP => ISO_A2_MNP,
            NOR => ISO_A2_NOR,
            OMN => ISO_A2_OMN,
            PAK => ISO_A2_PAK,
            PLW => ISO_A2_PLW,
            PSE => ISO_A2_PSE,
            PAN => ISO_A2_PAN,
            PNG => ISO_A2_PNG,
            PRY => ISO_A2_PRY,
            PER => ISO_A2_PER,
            PHL => ISO_A2_PHL,
            PCN => ISO_A2_PCN,
            POL => ISO_A2_POL,
            PRT => ISO_A2_PRT,
            PRI => ISO_A2_PRI,
            QAT => ISO_A2_QAT,
            REU => ISO_A2_REU,
            ROU => ISO_A2_ROU,
            RUS => ISO_A2_RUS,
            RWA => ISO_A2_RWA,
            BLM => ISO_A2_BLM,
            SHN => ISO_A2_SHN,
            KNA => ISO_A2_KNA,
            LCA => ISO_A2_LCA,
            MAF => ISO_A2_MAF,
            SPM => ISO_A2_SPM,
            VCT => ISO_A2_VCT,
            WSM => ISO_A2_WSM,
            SMR => ISO_A2_SMR,
            STP => ISO_A2_STP,
            SAU => ISO_A2_SAU,
            SEN => ISO_A2_SEN,
            SRB => ISO_A2_SRB,
            SYC => ISO_A2_SYC,
            SLE => ISO_A2_SLE,
            SGP => ISO_A2_SGP,
            SXM => ISO_A2_SXM,
            SVK => ISO_A2_SVK,
            SVN => ISO_A2_SVN,
            SLB => ISO_A2_SLB,
            SOM => ISO_A2_SOM,
            ZAF => ISO_A2_ZAF,
            SGS => ISO_A2_SGS,
            SSD => ISO_A2_SSD,
            ESP => ISO_A2_ESP,
            LKA => ISO_A2_LKA,
            SDN => ISO_A2_SDN,
            SUR => ISO_A2_SUR,
            SJM => ISO_A2_SJM,
            SWZ => ISO_A2_SWZ,
            SWE => ISO_A2_SWE,
            CHE => ISO_A2_CHE,
            SYR => ISO_A2_SYR,
            TWN => ISO_A2_TWN,
            TJK => ISO_A2_TJK,
            TZA => ISO_A2_TZA,
            THA => ISO_A2_THA,
            TLS => ISO_A2_TLS,
            TGO => ISO_A2_TGO,
            TKL => ISO_A2_TKL,
            TON => ISO_A2_TON,
            TTO => ISO_A2_TTO,
            TUN => ISO_A2_TUN,
            TUR => ISO_A2_TUR,
            TKM => ISO_A2_TKM,
            TCA => ISO_A2_TCA,
            TUV => ISO_A2_TUV,
            UGA => ISO_A2_UGA,
            UKR => ISO_A2_UKR,
            ARE => ISO_A2_ARE,
            GBR => ISO_A2_GBR,
            USA => ISO_A2_USA,
            UMI => ISO_A2_UMI,
            URY => ISO_A2_URY,
            UZB => ISO_A2_UZB,
            VUT => ISO_A2_VUT,
            VEN => ISO_A2_VEN,
            VNM => ISO_A2_VNM,
            VGB => ISO_A2_VGB,
            VIR => ISO_A2_VIR,
            WLF => ISO_A2_WLF,
            ESH => ISO_A2_ESH,
            YEM => ISO_A2_YEM,
            ZMB => ISO_A2_ZMB,
            ZWE => ISO_A2_ZWE,
        }
    }

    /// Returns the uppercase three-character ISO 3166-1 string
    pub fn alpha3(&self) -> &'static str {
        use self::CountryCode::*;
        use alpha3::*;
        match *self {
            AFG => ISO_A3_AFG,
            ALA => ISO_A3_ALA,
            ALB => ISO_A3_ALB,
            DZA => ISO_A3_DZA,
            ASM => ISO_A3_ASM,
            AND => ISO_A3_AND,
            AGO => ISO_A3_AGO,
            AIA => ISO_A3_AIA,
            ATA => ISO_A3_ATA,
            ATG => ISO_A3_ATG,
            ARG => ISO_A3_ARG,
            ARM => ISO_A3_ARM,
            ABW => ISO_A3_ABW,
            AUS => ISO_A3_AUS,
            AUT => ISO_A3_AUT,
            AZE => ISO_A3_AZE,
            BHS => ISO_A3_BHS,
            BHR => ISO_A3_BHR,
            BGD => ISO_A3_BGD,
            BRB => ISO_A3_BRB,
            BLR => ISO_A3_BLR,
            BEL => ISO_A3_BEL,
            BLZ => ISO_A3_BLZ,
            BEN => ISO_A3_BEN,
            BMU => ISO_A3_BMU,
            BTN => ISO_A3_BTN,
            BOL => ISO_A3_BOL,
            BES => ISO_A3_BES,
            BIH => ISO_A3_BIH,
            BWA => ISO_A3_BWA,
            BVT => ISO_A3_BVT,
            BRA => ISO_A3_BRA,
            IOT => ISO_A3_IOT,
            BRN => ISO_A3_BRN,
            BGR => ISO_A3_BGR,
            BFA => ISO_A3_BFA,
            BDI => ISO_A3_BDI,
            CPV => ISO_A3_CPV,
            KHM => ISO_A3_KHM,
            CMR => ISO_A3_CMR,
            CAN => ISO_A3_CAN,
            CYM => ISO_A3_CYM,
            CAF => ISO_A3_CAF,
            TCD => ISO_A3_TCD,
            CHL => ISO_A3_CHL,
            CHN => ISO_A3_CHN,
            CXR => ISO_A3_CXR,
            CCK => ISO_A3_CCK,
            COL => ISO_A3_COL,
            COM => ISO_A3_COM,
            COG => ISO_A3_COG,
            COD => ISO_A3_COD,
            COK => ISO_A3_COK,
            CRI => ISO_A3_CRI,
            CIV => ISO_A3_CIV,
            HRV => ISO_A3_HRV,
            CUB => ISO_A3_CUB,
            CUW => ISO_A3_CUW,
            CYP => ISO_A3_CYP,
            CZE => ISO_A3_CZE,
            DNK => ISO_A3_DNK,
            DJI => ISO_A3_DJI,
            DMA => ISO_A3_DMA,
            DOM => ISO_A3_DOM,
            ECU => ISO_A3_ECU,
            EGY => ISO_A3_EGY,
            SLV => ISO_A3_SLV,
            GNQ => ISO_A3_GNQ,
            ERI => ISO_A3_ERI,
            EST => ISO_A3_EST,
            ETH => ISO_A3_ETH,
            FLK => ISO_A3_FLK,
            FRO => ISO_A3_FRO,
            FJI => ISO_A3_FJI,
            FIN => ISO_A3_FIN,
            FRA => ISO_A3_FRA,
            GUF => ISO_A3_GUF,
            PYF => ISO_A3_PYF,
            ATF => ISO_A3_ATF,
            GAB => ISO_A3_GAB,
            GMB => ISO_A3_GMB,
            GEO => ISO_A3_GEO,
            DEU => ISO_A3_DEU,
            GHA => ISO_A3_GHA,
            GIB => ISO_A3_GIB,
            GRC => ISO_A3_GRC,
            GRL => ISO_A3_GRL,
            GRD => ISO_A3_GRD,
            GLP => ISO_A3_GLP,
            GUM => ISO_A3_GUM,
            GTM => ISO_A3_GTM,
            GGY => ISO_A3_GGY,
            GIN => ISO_A3_GIN,
            GNB => ISO_A3_GNB,
            GUY => ISO_A3_GUY,
            HTI => ISO_A3_HTI,
            HMD => ISO_A3_HMD,
            VAT => ISO_A3_VAT,
            HND => ISO_A3_HND,
            HKG => ISO_A3_HKG,
            HUN => ISO_A3_HUN,
            ISL => ISO_A3_ISL,
            IND => ISO_A3_IND,
            IDN => ISO_A3_IDN,
            IRN => ISO_A3_IRN,
            IRQ => ISO_A3_IRQ,
            IRL => ISO_A3_IRL,
            IMN => ISO_A3_IMN,
            ISR => ISO_A3_ISR,
            ITA => ISO_A3_ITA,
            JAM => ISO_A3_JAM,
            JPN => ISO_A3_JPN,
            JEY => ISO_A3_JEY,
            JOR => ISO_A3_JOR,
            KAZ => ISO_A3_KAZ,
            KEN => ISO_A3_KEN,
            KIR => ISO_A3_KIR,
            PRK => ISO_A3_PRK,
            KOR => ISO_A3_KOR,
            KWT => ISO_A3_KWT,
            KGZ => ISO_A3_KGZ,
            LAO => ISO_A3_LAO,
            LVA => ISO_A3_LVA,
            LBN => ISO_A3_LBN,
            LSO => ISO_A3_LSO,
            LBR => ISO_A3_LBR,
            LBY => ISO_A3_LBY,
            LIE => ISO_A3_LIE,
            LTU => ISO_A3_LTU,
            LUX => ISO_A3_LUX,
            MAC => ISO_A3_MAC,
            MKD => ISO_A3_MKD,
            MDG => ISO_A3_MDG,
            MWI => ISO_A3_MWI,
            MYS => ISO_A3_MYS,
            MDV => ISO_A3_MDV,
            MLI => ISO_A3_MLI,
            MLT => ISO_A3_MLT,
            MHL => ISO_A3_MHL,
            MTQ => ISO_A3_MTQ,
            MRT => ISO_A3_MRT,
            MUS => ISO_A3_MUS,
            MYT => ISO_A3_MYT,
            MEX => ISO_A3_MEX,
            FSM => ISO_A3_FSM,
            MDA => ISO_A3_MDA,
            MCO => ISO_A3_MCO,
            MNG => ISO_A3_MNG,
            MNE => ISO_A3_MNE,
            MSR => ISO_A3_MSR,
            MAR => ISO_A3_MAR,
            MOZ => ISO_A3_MOZ,
            MMR => ISO_A3_MMR,
            NAM => ISO_A3_NAM,
            NRU => ISO_A3_NRU,
            NPL => ISO_A3_NPL,
            NLD => ISO_A3_NLD,
            NCL => ISO_A3_NCL,
            NZL => ISO_A3_NZL,
            NIC => ISO_A3_NIC,
            NER => ISO_A3_NER,
            NGA => ISO_A3_NGA,
            NIU => ISO_A3_NIU,
            NFK => ISO_A3_NFK,
            MNP => ISO_A3_MNP,
            NOR => ISO_A3_NOR,
            OMN => ISO_A3_OMN,
            PAK => ISO_A3_PAK,
            PLW => ISO_A3_PLW,
            PSE => ISO_A3_PSE,
            PAN => ISO_A3_PAN,
            PNG => ISO_A3_PNG,
            PRY => ISO_A3_PRY,
            PER => ISO_A3_PER,
            PHL => ISO_A3_PHL,
            PCN => ISO_A3_PCN,
            POL => ISO_A3_POL,
            PRT => ISO_A3_PRT,
            PRI => ISO_A3_PRI,
            QAT => ISO_A3_QAT,
            REU => ISO_A3_REU,
            ROU => ISO_A3_ROU,
            RUS => ISO_A3_RUS,
            RWA => ISO_A3_RWA,
            BLM => ISO_A3_BLM,
            SHN => ISO_A3_SHN,
            KNA => ISO_A3_KNA,
            LCA => ISO_A3_LCA,
            MAF => ISO_A3_MAF,
            SPM => ISO_A3_SPM,
            VCT => ISO_A3_VCT,
            WSM => ISO_A3_WSM,
            SMR => ISO_A3_SMR,
            STP => ISO_A3_STP,
            SAU => ISO_A3_SAU,
            SEN => ISO_A3_SEN,
            SRB => ISO_A3_SRB,
            SYC => ISO_A3_SYC,
            SLE => ISO_A3_SLE,
            SGP => ISO_A3_SGP,
            SXM => ISO_A3_SXM,
            SVK => ISO_A3_SVK,
            SVN => ISO_A3_SVN,
            SLB => ISO_A3_SLB,
            SOM => ISO_A3_SOM,
            ZAF => ISO_A3_ZAF,
            SGS => ISO_A3_SGS,
            SSD => ISO_A3_SSD,
            ESP => ISO_A3_ESP,
            LKA => ISO_A3_LKA,
            SDN => ISO_A3_SDN,
            SUR => ISO_A3_SUR,
            SJM => ISO_A3_SJM,
            SWZ => ISO_A3_SWZ,
            SWE => ISO_A3_SWE,
            CHE => ISO_A3_CHE,
            SYR => ISO_A3_SYR,
            TWN => ISO_A3_TWN,
            TJK => ISO_A3_TJK,
            TZA => ISO_A3_TZA,
            THA => ISO_A3_THA,
            TLS => ISO_A3_TLS,
            TGO => ISO_A3_TGO,
            TKL => ISO_A3_TKL,
            TON => ISO_A3_TON,
            TTO => ISO_A3_TTO,
            TUN => ISO_A3_TUN,
            TUR => ISO_A3_TUR,
            TKM => ISO_A3_TKM,
            TCA => ISO_A3_TCA,
            TUV => ISO_A3_TUV,
            UGA => ISO_A3_UGA,
            UKR => ISO_A3_UKR,
            ARE => ISO_A3_ARE,
            GBR => ISO_A3_GBR,
            USA => ISO_A3_USA,
            UMI => ISO_A3_UMI,
            URY => ISO_A3_URY,
            UZB => ISO_A3_UZB,
            VUT => ISO_A3_VUT,
            VEN => ISO_A3_VEN,
            VNM => ISO_A3_VNM,
            VGB => ISO_A3_VGB,
            VIR => ISO_A3_VIR,
            WLF => ISO_A3_WLF,
            ESH => ISO_A3_ESH,
            YEM => ISO_A3_YEM,
            ZMB => ISO_A3_ZMB,
            ZWE => ISO_A3_ZWE,
        }
    }

    /// Attempts to determine the ISO 3166-1 CountryCode for the given two-character string,
    /// assuming it is in upper-case characters
    pub fn for_alpha2(value: &str) -> Result<CountryCode, CountryCodeParseErr> {
        use CountryCode::*;
        use alpha2::*;
        match value {
            ISO_A2_AFG => Ok(AFG),
            ISO_A2_ALA => Ok(ALA),
            ISO_A2_ALB => Ok(ALB),
            ISO_A2_DZA => Ok(DZA),
            ISO_A2_ASM => Ok(ASM),
            ISO_A2_AND => Ok(AND),
            ISO_A2_AGO => Ok(AGO),
            ISO_A2_AIA => Ok(AIA),
            ISO_A2_ATA => Ok(ATA),
            ISO_A2_ATG => Ok(ATG),
            ISO_A2_ARG => Ok(ARG),
            ISO_A2_ARM => Ok(ARM),
            ISO_A2_ABW => Ok(ABW),
            ISO_A2_AUS => Ok(AUS),
            ISO_A2_AUT => Ok(AUT),
            ISO_A2_AZE => Ok(AZE),
            ISO_A2_BHS => Ok(BHS),
            ISO_A2_BHR => Ok(BHR),
            ISO_A2_BGD => Ok(BGD),
            ISO_A2_BRB => Ok(BRB),
            ISO_A2_BLR => Ok(BLR),
            ISO_A2_BEL => Ok(BEL),
            ISO_A2_BLZ => Ok(BLZ),
            ISO_A2_BEN => Ok(BEN),
            ISO_A2_BMU => Ok(BMU),
            ISO_A2_BTN => Ok(BTN),
            ISO_A2_BOL => Ok(BOL),
            ISO_A2_BES => Ok(BES),
            ISO_A2_BIH => Ok(BIH),
            ISO_A2_BWA => Ok(BWA),
            ISO_A2_BVT => Ok(BVT),
            ISO_A2_BRA => Ok(BRA),
            ISO_A2_IOT => Ok(IOT),
            ISO_A2_BRN => Ok(BRN),
            ISO_A2_BGR => Ok(BGR),
            ISO_A2_BFA => Ok(BFA),
            ISO_A2_BDI => Ok(BDI),
            ISO_A2_CPV => Ok(CPV),
            ISO_A2_KHM => Ok(KHM),
            ISO_A2_CMR => Ok(CMR),
            ISO_A2_CAN => Ok(CAN),
            ISO_A2_CYM => Ok(CYM),
            ISO_A2_CAF => Ok(CAF),
            ISO_A2_TCD => Ok(TCD),
            ISO_A2_CHL => Ok(CHL),
            ISO_A2_CHN => Ok(CHN),
            ISO_A2_CXR => Ok(CXR),
            ISO_A2_CCK => Ok(CCK),
            ISO_A2_COL => Ok(COL),
            ISO_A2_COM => Ok(COM),
            ISO_A2_COG => Ok(COG),
            ISO_A2_COD => Ok(COD),
            ISO_A2_COK => Ok(COK),
            ISO_A2_CRI => Ok(CRI),
            ISO_A2_CIV => Ok(CIV),
            ISO_A2_HRV => Ok(HRV),
            ISO_A2_CUB => Ok(CUB),
            ISO_A2_CUW => Ok(CUW),
            ISO_A2_CYP => Ok(CYP),
            ISO_A2_CZE => Ok(CZE),
            ISO_A2_DNK => Ok(DNK),
            ISO_A2_DJI => Ok(DJI),
            ISO_A2_DMA => Ok(DMA),
            ISO_A2_DOM => Ok(DOM),
            ISO_A2_ECU => Ok(ECU),
            ISO_A2_EGY => Ok(EGY),
            ISO_A2_SLV => Ok(SLV),
            ISO_A2_GNQ => Ok(GNQ),
            ISO_A2_ERI => Ok(ERI),
            ISO_A2_EST => Ok(EST),
            ISO_A2_ETH => Ok(ETH),
            ISO_A2_FLK => Ok(FLK),
            ISO_A2_FRO => Ok(FRO),
            ISO_A2_FJI => Ok(FJI),
            ISO_A2_FIN => Ok(FIN),
            ISO_A2_FRA => Ok(FRA),
            ISO_A2_GUF => Ok(GUF),
            ISO_A2_PYF => Ok(PYF),
            ISO_A2_ATF => Ok(ATF),
            ISO_A2_GAB => Ok(GAB),
            ISO_A2_GMB => Ok(GMB),
            ISO_A2_GEO => Ok(GEO),
            ISO_A2_DEU => Ok(DEU),
            ISO_A2_GHA => Ok(GHA),
            ISO_A2_GIB => Ok(GIB),
            ISO_A2_GRC => Ok(GRC),
            ISO_A2_GRL => Ok(GRL),
            ISO_A2_GRD => Ok(GRD),
            ISO_A2_GLP => Ok(GLP),
            ISO_A2_GUM => Ok(GUM),
            ISO_A2_GTM => Ok(GTM),
            ISO_A2_GGY => Ok(GGY),
            ISO_A2_GIN => Ok(GIN),
            ISO_A2_GNB => Ok(GNB),
            ISO_A2_GUY => Ok(GUY),
            ISO_A2_HTI => Ok(HTI),
            ISO_A2_HMD => Ok(HMD),
            ISO_A2_VAT => Ok(VAT),
            ISO_A2_HND => Ok(HND),
            ISO_A2_HKG => Ok(HKG),
            ISO_A2_HUN => Ok(HUN),
            ISO_A2_ISL => Ok(ISL),
            ISO_A2_IND => Ok(IND),
            ISO_A2_IDN => Ok(IDN),
            ISO_A2_IRN => Ok(IRN),
            ISO_A2_IRQ => Ok(IRQ),
            ISO_A2_IRL => Ok(IRL),
            ISO_A2_IMN => Ok(IMN),
            ISO_A2_ISR => Ok(ISR),
            ISO_A2_ITA => Ok(ITA),
            ISO_A2_JAM => Ok(JAM),
            ISO_A2_JPN => Ok(JPN),
            ISO_A2_JEY => Ok(JEY),
            ISO_A2_JOR => Ok(JOR),
            ISO_A2_KAZ => Ok(KAZ),
            ISO_A2_KEN => Ok(KEN),
            ISO_A2_KIR => Ok(KIR),
            ISO_A2_PRK => Ok(PRK),
            ISO_A2_KOR => Ok(KOR),
            ISO_A2_KWT => Ok(KWT),
            ISO_A2_KGZ => Ok(KGZ),
            ISO_A2_LAO => Ok(LAO),
            ISO_A2_LVA => Ok(LVA),
            ISO_A2_LBN => Ok(LBN),
            ISO_A2_LSO => Ok(LSO),
            ISO_A2_LBR => Ok(LBR),
            ISO_A2_LBY => Ok(LBY),
            ISO_A2_LIE => Ok(LIE),
            ISO_A2_LTU => Ok(LTU),
            ISO_A2_LUX => Ok(LUX),
            ISO_A2_MAC => Ok(MAC),
            ISO_A2_MKD => Ok(MKD),
            ISO_A2_MDG => Ok(MDG),
            ISO_A2_MWI => Ok(MWI),
            ISO_A2_MYS => Ok(MYS),
            ISO_A2_MDV => Ok(MDV),
            ISO_A2_MLI => Ok(MLI),
            ISO_A2_MLT => Ok(MLT),
            ISO_A2_MHL => Ok(MHL),
            ISO_A2_MTQ => Ok(MTQ),
            ISO_A2_MRT => Ok(MRT),
            ISO_A2_MUS => Ok(MUS),
            ISO_A2_MYT => Ok(MYT),
            ISO_A2_MEX => Ok(MEX),
            ISO_A2_FSM => Ok(FSM),
            ISO_A2_MDA => Ok(MDA),
            ISO_A2_MCO => Ok(MCO),
            ISO_A2_MNG => Ok(MNG),
            ISO_A2_MNE => Ok(MNE),
            ISO_A2_MSR => Ok(MSR),
            ISO_A2_MAR => Ok(MAR),
            ISO_A2_MOZ => Ok(MOZ),
            ISO_A2_MMR => Ok(MMR),
            ISO_A2_NAM => Ok(NAM),
            ISO_A2_NRU => Ok(NRU),
            ISO_A2_NPL => Ok(NPL),
            ISO_A2_NLD => Ok(NLD),
            ISO_A2_NCL => Ok(NCL),
            ISO_A2_NZL => Ok(NZL),
            ISO_A2_NIC => Ok(NIC),
            ISO_A2_NER => Ok(NER),
            ISO_A2_NGA => Ok(NGA),
            ISO_A2_NIU => Ok(NIU),
            ISO_A2_NFK => Ok(NFK),
            ISO_A2_MNP => Ok(MNP),
            ISO_A2_NOR => Ok(NOR),
            ISO_A2_OMN => Ok(OMN),
            ISO_A2_PAK => Ok(PAK),
            ISO_A2_PLW => Ok(PLW),
            ISO_A2_PSE => Ok(PSE),
            ISO_A2_PAN => Ok(PAN),
            ISO_A2_PNG => Ok(PNG),
            ISO_A2_PRY => Ok(PRY),
            ISO_A2_PER => Ok(PER),
            ISO_A2_PHL => Ok(PHL),
            ISO_A2_PCN => Ok(PCN),
            ISO_A2_POL => Ok(POL),
            ISO_A2_PRT => Ok(PRT),
            ISO_A2_PRI => Ok(PRI),
            ISO_A2_QAT => Ok(QAT),
            ISO_A2_REU => Ok(REU),
            ISO_A2_ROU => Ok(ROU),
            ISO_A2_RUS => Ok(RUS),
            ISO_A2_RWA => Ok(RWA),
            ISO_A2_BLM => Ok(BLM),
            ISO_A2_SHN => Ok(SHN),
            ISO_A2_KNA => Ok(KNA),
            ISO_A2_LCA => Ok(LCA),
            ISO_A2_MAF => Ok(MAF),
            ISO_A2_SPM => Ok(SPM),
            ISO_A2_VCT => Ok(VCT),
            ISO_A2_WSM => Ok(WSM),
            ISO_A2_SMR => Ok(SMR),
            ISO_A2_STP => Ok(STP),
            ISO_A2_SAU => Ok(SAU),
            ISO_A2_SEN => Ok(SEN),
            ISO_A2_SRB => Ok(SRB),
            ISO_A2_SYC => Ok(SYC),
            ISO_A2_SLE => Ok(SLE),
            ISO_A2_SGP => Ok(SGP),
            ISO_A2_SXM => Ok(SXM),
            ISO_A2_SVK => Ok(SVK),
            ISO_A2_SVN => Ok(SVN),
            ISO_A2_SLB => Ok(SLB),
            ISO_A2_SOM => Ok(SOM),
            ISO_A2_ZAF => Ok(ZAF),
            ISO_A2_SGS => Ok(SGS),
            ISO_A2_SSD => Ok(SSD),
            ISO_A2_ESP => Ok(ESP),
            ISO_A2_LKA => Ok(LKA),
            ISO_A2_SDN => Ok(SDN),
            ISO_A2_SUR => Ok(SUR),
            ISO_A2_SJM => Ok(SJM),
            ISO_A2_SWZ => Ok(SWZ),
            ISO_A2_SWE => Ok(SWE),
            ISO_A2_CHE => Ok(CHE),
            ISO_A2_SYR => Ok(SYR),
            ISO_A2_TWN => Ok(TWN),
            ISO_A2_TJK => Ok(TJK),
            ISO_A2_TZA => Ok(TZA),
            ISO_A2_THA => Ok(THA),
            ISO_A2_TLS => Ok(TLS),
            ISO_A2_TGO => Ok(TGO),
            ISO_A2_TKL => Ok(TKL),
            ISO_A2_TON => Ok(TON),
            ISO_A2_TTO => Ok(TTO),
            ISO_A2_TUN => Ok(TUN),
            ISO_A2_TUR => Ok(TUR),
            ISO_A2_TKM => Ok(TKM),
            ISO_A2_TCA => Ok(TCA),
            ISO_A2_TUV => Ok(TUV),
            ISO_A2_UGA => Ok(UGA),
            ISO_A2_UKR => Ok(UKR),
            ISO_A2_ARE => Ok(ARE),
            ISO_A2_GBR => Ok(GBR),
            ISO_A2_USA => Ok(USA),
            ISO_A2_UMI => Ok(UMI),
            ISO_A2_URY => Ok(URY),
            ISO_A2_UZB => Ok(UZB),
            ISO_A2_VUT => Ok(VUT),
            ISO_A2_VEN => Ok(VEN),
            ISO_A2_VNM => Ok(VNM),
            ISO_A2_VGB => Ok(VGB),
            ISO_A2_VIR => Ok(VIR),
            ISO_A2_WLF => Ok(WLF),
            ISO_A2_ESH => Ok(ESH),
            ISO_A2_YEM => Ok(YEM),
            ISO_A2_ZMB => Ok(ZMB),
            ISO_A2_ZWE => Ok(ZWE),
            x => Err(CountryCodeParseErr::InvalidAlpha2 {
                unknown: String::from(x),
            }),
        }
    }

    /// Attempts to determine the ISO 3166-1 CountryCode for the given two-character string,
    /// making no assumption as to the case-ness of the input
    pub fn for_alpha2_caseless(value: &str) -> Result<CountryCode, CountryCodeParseErr> {
        let uppercase = value.to_uppercase();
        CountryCode::for_alpha2(uppercase.as_ref())
    }

    /// Attempts to determine the ISO 3166-1 CountryCode for the given three-character string,
    /// assuming it is in upper-case characters
    pub fn for_alpha3(value: &str) -> Result<CountryCode, CountryCodeParseErr> {
        use CountryCode::*;
        use alpha3::*;
        match value {
            ISO_A3_AFG => Ok(AFG),
            ISO_A3_ALA => Ok(ALA),
            ISO_A3_ALB => Ok(ALB),
            ISO_A3_DZA => Ok(DZA),
            ISO_A3_ASM => Ok(ASM),
            ISO_A3_AND => Ok(AND),
            ISO_A3_AGO => Ok(AGO),
            ISO_A3_AIA => Ok(AIA),
            ISO_A3_ATA => Ok(ATA),
            ISO_A3_ATG => Ok(ATG),
            ISO_A3_ARG => Ok(ARG),
            ISO_A3_ARM => Ok(ARM),
            ISO_A3_ABW => Ok(ABW),
            ISO_A3_AUS => Ok(AUS),
            ISO_A3_AUT => Ok(AUT),
            ISO_A3_AZE => Ok(AZE),
            ISO_A3_BHS => Ok(BHS),
            ISO_A3_BHR => Ok(BHR),
            ISO_A3_BGD => Ok(BGD),
            ISO_A3_BRB => Ok(BRB),
            ISO_A3_BLR => Ok(BLR),
            ISO_A3_BEL => Ok(BEL),
            ISO_A3_BLZ => Ok(BLZ),
            ISO_A3_BEN => Ok(BEN),
            ISO_A3_BMU => Ok(BMU),
            ISO_A3_BTN => Ok(BTN),
            ISO_A3_BOL => Ok(BOL),
            ISO_A3_BES => Ok(BES),
            ISO_A3_BIH => Ok(BIH),
            ISO_A3_BWA => Ok(BWA),
            ISO_A3_BVT => Ok(BVT),
            ISO_A3_BRA => Ok(BRA),
            ISO_A3_IOT => Ok(IOT),
            ISO_A3_BRN => Ok(BRN),
            ISO_A3_BGR => Ok(BGR),
            ISO_A3_BFA => Ok(BFA),
            ISO_A3_BDI => Ok(BDI),
            ISO_A3_CPV => Ok(CPV),
            ISO_A3_KHM => Ok(KHM),
            ISO_A3_CMR => Ok(CMR),
            ISO_A3_CAN => Ok(CAN),
            ISO_A3_CYM => Ok(CYM),
            ISO_A3_CAF => Ok(CAF),
            ISO_A3_TCD => Ok(TCD),
            ISO_A3_CHL => Ok(CHL),
            ISO_A3_CHN => Ok(CHN),
            ISO_A3_CXR => Ok(CXR),
            ISO_A3_CCK => Ok(CCK),
            ISO_A3_COL => Ok(COL),
            ISO_A3_COM => Ok(COM),
            ISO_A3_COG => Ok(COG),
            ISO_A3_COD => Ok(COD),
            ISO_A3_COK => Ok(COK),
            ISO_A3_CRI => Ok(CRI),
            ISO_A3_CIV => Ok(CIV),
            ISO_A3_HRV => Ok(HRV),
            ISO_A3_CUB => Ok(CUB),
            ISO_A3_CUW => Ok(CUW),
            ISO_A3_CYP => Ok(CYP),
            ISO_A3_CZE => Ok(CZE),
            ISO_A3_DNK => Ok(DNK),
            ISO_A3_DJI => Ok(DJI),
            ISO_A3_DMA => Ok(DMA),
            ISO_A3_DOM => Ok(DOM),
            ISO_A3_ECU => Ok(ECU),
            ISO_A3_EGY => Ok(EGY),
            ISO_A3_SLV => Ok(SLV),
            ISO_A3_GNQ => Ok(GNQ),
            ISO_A3_ERI => Ok(ERI),
            ISO_A3_EST => Ok(EST),
            ISO_A3_ETH => Ok(ETH),
            ISO_A3_FLK => Ok(FLK),
            ISO_A3_FRO => Ok(FRO),
            ISO_A3_FJI => Ok(FJI),
            ISO_A3_FIN => Ok(FIN),
            ISO_A3_FRA => Ok(FRA),
            ISO_A3_GUF => Ok(GUF),
            ISO_A3_PYF => Ok(PYF),
            ISO_A3_ATF => Ok(ATF),
            ISO_A3_GAB => Ok(GAB),
            ISO_A3_GMB => Ok(GMB),
            ISO_A3_GEO => Ok(GEO),
            ISO_A3_DEU => Ok(DEU),
            ISO_A3_GHA => Ok(GHA),
            ISO_A3_GIB => Ok(GIB),
            ISO_A3_GRC => Ok(GRC),
            ISO_A3_GRL => Ok(GRL),
            ISO_A3_GRD => Ok(GRD),
            ISO_A3_GLP => Ok(GLP),
            ISO_A3_GUM => Ok(GUM),
            ISO_A3_GTM => Ok(GTM),
            ISO_A3_GGY => Ok(GGY),
            ISO_A3_GIN => Ok(GIN),
            ISO_A3_GNB => Ok(GNB),
            ISO_A3_GUY => Ok(GUY),
            ISO_A3_HTI => Ok(HTI),
            ISO_A3_HMD => Ok(HMD),
            ISO_A3_VAT => Ok(VAT),
            ISO_A3_HND => Ok(HND),
            ISO_A3_HKG => Ok(HKG),
            ISO_A3_HUN => Ok(HUN),
            ISO_A3_ISL => Ok(ISL),
            ISO_A3_IND => Ok(IND),
            ISO_A3_IDN => Ok(IDN),
            ISO_A3_IRN => Ok(IRN),
            ISO_A3_IRQ => Ok(IRQ),
            ISO_A3_IRL => Ok(IRL),
            ISO_A3_IMN => Ok(IMN),
            ISO_A3_ISR => Ok(ISR),
            ISO_A3_ITA => Ok(ITA),
            ISO_A3_JAM => Ok(JAM),
            ISO_A3_JPN => Ok(JPN),
            ISO_A3_JEY => Ok(JEY),
            ISO_A3_JOR => Ok(JOR),
            ISO_A3_KAZ => Ok(KAZ),
            ISO_A3_KEN => Ok(KEN),
            ISO_A3_KIR => Ok(KIR),
            ISO_A3_PRK => Ok(PRK),
            ISO_A3_KOR => Ok(KOR),
            ISO_A3_KWT => Ok(KWT),
            ISO_A3_KGZ => Ok(KGZ),
            ISO_A3_LAO => Ok(LAO),
            ISO_A3_LVA => Ok(LVA),
            ISO_A3_LBN => Ok(LBN),
            ISO_A3_LSO => Ok(LSO),
            ISO_A3_LBR => Ok(LBR),
            ISO_A3_LBY => Ok(LBY),
            ISO_A3_LIE => Ok(LIE),
            ISO_A3_LTU => Ok(LTU),
            ISO_A3_LUX => Ok(LUX),
            ISO_A3_MAC => Ok(MAC),
            ISO_A3_MKD => Ok(MKD),
            ISO_A3_MDG => Ok(MDG),
            ISO_A3_MWI => Ok(MWI),
            ISO_A3_MYS => Ok(MYS),
            ISO_A3_MDV => Ok(MDV),
            ISO_A3_MLI => Ok(MLI),
            ISO_A3_MLT => Ok(MLT),
            ISO_A3_MHL => Ok(MHL),
            ISO_A3_MTQ => Ok(MTQ),
            ISO_A3_MRT => Ok(MRT),
            ISO_A3_MUS => Ok(MUS),
            ISO_A3_MYT => Ok(MYT),
            ISO_A3_MEX => Ok(MEX),
            ISO_A3_FSM => Ok(FSM),
            ISO_A3_MDA => Ok(MDA),
            ISO_A3_MCO => Ok(MCO),
            ISO_A3_MNG => Ok(MNG),
            ISO_A3_MNE => Ok(MNE),
            ISO_A3_MSR => Ok(MSR),
            ISO_A3_MAR => Ok(MAR),
            ISO_A3_MOZ => Ok(MOZ),
            ISO_A3_MMR => Ok(MMR),
            ISO_A3_NAM => Ok(NAM),
            ISO_A3_NRU => Ok(NRU),
            ISO_A3_NPL => Ok(NPL),
            ISO_A3_NLD => Ok(NLD),
            ISO_A3_NCL => Ok(NCL),
            ISO_A3_NZL => Ok(NZL),
            ISO_A3_NIC => Ok(NIC),
            ISO_A3_NER => Ok(NER),
            ISO_A3_NGA => Ok(NGA),
            ISO_A3_NIU => Ok(NIU),
            ISO_A3_NFK => Ok(NFK),
            ISO_A3_MNP => Ok(MNP),
            ISO_A3_NOR => Ok(NOR),
            ISO_A3_OMN => Ok(OMN),
            ISO_A3_PAK => Ok(PAK),
            ISO_A3_PLW => Ok(PLW),
            ISO_A3_PSE => Ok(PSE),
            ISO_A3_PAN => Ok(PAN),
            ISO_A3_PNG => Ok(PNG),
            ISO_A3_PRY => Ok(PRY),
            ISO_A3_PER => Ok(PER),
            ISO_A3_PHL => Ok(PHL),
            ISO_A3_PCN => Ok(PCN),
            ISO_A3_POL => Ok(POL),
            ISO_A3_PRT => Ok(PRT),
            ISO_A3_PRI => Ok(PRI),
            ISO_A3_QAT => Ok(QAT),
            ISO_A3_REU => Ok(REU),
            ISO_A3_ROU => Ok(ROU),
            ISO_A3_RUS => Ok(RUS),
            ISO_A3_RWA => Ok(RWA),
            ISO_A3_BLM => Ok(BLM),
            ISO_A3_SHN => Ok(SHN),
            ISO_A3_KNA => Ok(KNA),
            ISO_A3_LCA => Ok(LCA),
            ISO_A3_MAF => Ok(MAF),
            ISO_A3_SPM => Ok(SPM),
            ISO_A3_VCT => Ok(VCT),
            ISO_A3_WSM => Ok(WSM),
            ISO_A3_SMR => Ok(SMR),
            ISO_A3_STP => Ok(STP),
            ISO_A3_SAU => Ok(SAU),
            ISO_A3_SEN => Ok(SEN),
            ISO_A3_SRB => Ok(SRB),
            ISO_A3_SYC => Ok(SYC),
            ISO_A3_SLE => Ok(SLE),
            ISO_A3_SGP => Ok(SGP),
            ISO_A3_SXM => Ok(SXM),
            ISO_A3_SVK => Ok(SVK),
            ISO_A3_SVN => Ok(SVN),
            ISO_A3_SLB => Ok(SLB),
            ISO_A3_SOM => Ok(SOM),
            ISO_A3_ZAF => Ok(ZAF),
            ISO_A3_SGS => Ok(SGS),
            ISO_A3_SSD => Ok(SSD),
            ISO_A3_ESP => Ok(ESP),
            ISO_A3_LKA => Ok(LKA),
            ISO_A3_SDN => Ok(SDN),
            ISO_A3_SUR => Ok(SUR),
            ISO_A3_SJM => Ok(SJM),
            ISO_A3_SWZ => Ok(SWZ),
            ISO_A3_SWE => Ok(SWE),
            ISO_A3_CHE => Ok(CHE),
            ISO_A3_SYR => Ok(SYR),
            ISO_A3_TWN => Ok(TWN),
            ISO_A3_TJK => Ok(TJK),
            ISO_A3_TZA => Ok(TZA),
            ISO_A3_THA => Ok(THA),
            ISO_A3_TLS => Ok(TLS),
            ISO_A3_TGO => Ok(TGO),
            ISO_A3_TKL => Ok(TKL),
            ISO_A3_TON => Ok(TON),
            ISO_A3_TTO => Ok(TTO),
            ISO_A3_TUN => Ok(TUN),
            ISO_A3_TUR => Ok(TUR),
            ISO_A3_TKM => Ok(TKM),
            ISO_A3_TCA => Ok(TCA),
            ISO_A3_TUV => Ok(TUV),
            ISO_A3_UGA => Ok(UGA),
            ISO_A3_UKR => Ok(UKR),
            ISO_A3_ARE => Ok(ARE),
            ISO_A3_GBR => Ok(GBR),
            ISO_A3_USA => Ok(USA),
            ISO_A3_UMI => Ok(UMI),
            ISO_A3_URY => Ok(URY),
            ISO_A3_UZB => Ok(UZB),
            ISO_A3_VUT => Ok(VUT),
            ISO_A3_VEN => Ok(VEN),
            ISO_A3_VNM => Ok(VNM),
            ISO_A3_VGB => Ok(VGB),
            ISO_A3_VIR => Ok(VIR),
            ISO_A3_WLF => Ok(WLF),
            ISO_A3_ESH => Ok(ESH),
            ISO_A3_YEM => Ok(YEM),
            ISO_A3_ZMB => Ok(ZMB),
            ISO_A3_ZWE => Ok(ZWE),
            x => Err(CountryCodeParseErr::InvalidAlpha3 {
                unknown: String::from(x),
            }),
        }
    }

    /// Attempts to determine the ISO 3166-1 CountryCode for the given three-character string,
    /// making no assumption as to the case-ness of the input
    pub fn for_alpha3_caseless(value: &str) -> Result<CountryCode, CountryCodeParseErr> {
        let uppercase = value.to_uppercase();
        CountryCode::for_alpha3(uppercase.as_ref())
    }

    /// Attempts to determine the ISO 3166-1 CountryCode for the given unsigned integer
    pub fn for_id(value: u32) -> Result<CountryCode, CountryCodeParseErr> {
        use CountryCode::*;
        use numeric::*;
        match value {
            ISO_NUM_AFG => Ok(AFG),
            ISO_NUM_ALA => Ok(ALA),
            ISO_NUM_ALB => Ok(ALB),
            ISO_NUM_DZA => Ok(DZA),
            ISO_NUM_ASM => Ok(ASM),
            ISO_NUM_AND => Ok(AND),
            ISO_NUM_AGO => Ok(AGO),
            ISO_NUM_AIA => Ok(AIA),
            ISO_NUM_ATA => Ok(ATA),
            ISO_NUM_ATG => Ok(ATG),
            ISO_NUM_ARG => Ok(ARG),
            ISO_NUM_ARM => Ok(ARM),
            ISO_NUM_ABW => Ok(ABW),
            ISO_NUM_AUS => Ok(AUS),
            ISO_NUM_AUT => Ok(AUT),
            ISO_NUM_AZE => Ok(AZE),
            ISO_NUM_BHS => Ok(BHS),
            ISO_NUM_BHR => Ok(BHR),
            ISO_NUM_BGD => Ok(BGD),
            ISO_NUM_BRB => Ok(BRB),
            ISO_NUM_BLR => Ok(BLR),
            ISO_NUM_BEL => Ok(BEL),
            ISO_NUM_BLZ => Ok(BLZ),
            ISO_NUM_BEN => Ok(BEN),
            ISO_NUM_BMU => Ok(BMU),
            ISO_NUM_BTN => Ok(BTN),
            ISO_NUM_BOL => Ok(BOL),
            ISO_NUM_BES => Ok(BES),
            ISO_NUM_BIH => Ok(BIH),
            ISO_NUM_BWA => Ok(BWA),
            ISO_NUM_BVT => Ok(BVT),
            ISO_NUM_BRA => Ok(BRA),
            ISO_NUM_IOT => Ok(IOT),
            ISO_NUM_BRN => Ok(BRN),
            ISO_NUM_BGR => Ok(BGR),
            ISO_NUM_BFA => Ok(BFA),
            ISO_NUM_BDI => Ok(BDI),
            ISO_NUM_CPV => Ok(CPV),
            ISO_NUM_KHM => Ok(KHM),
            ISO_NUM_CMR => Ok(CMR),
            ISO_NUM_CAN => Ok(CAN),
            ISO_NUM_CYM => Ok(CYM),
            ISO_NUM_CAF => Ok(CAF),
            ISO_NUM_TCD => Ok(TCD),
            ISO_NUM_CHL => Ok(CHL),
            ISO_NUM_CHN => Ok(CHN),
            ISO_NUM_CXR => Ok(CXR),
            ISO_NUM_CCK => Ok(CCK),
            ISO_NUM_COL => Ok(COL),
            ISO_NUM_COM => Ok(COM),
            ISO_NUM_COG => Ok(COG),
            ISO_NUM_COD => Ok(COD),
            ISO_NUM_COK => Ok(COK),
            ISO_NUM_CRI => Ok(CRI),
            ISO_NUM_CIV => Ok(CIV),
            ISO_NUM_HRV => Ok(HRV),
            ISO_NUM_CUB => Ok(CUB),
            ISO_NUM_CUW => Ok(CUW),
            ISO_NUM_CYP => Ok(CYP),
            ISO_NUM_CZE => Ok(CZE),
            ISO_NUM_DNK => Ok(DNK),
            ISO_NUM_DJI => Ok(DJI),
            ISO_NUM_DMA => Ok(DMA),
            ISO_NUM_DOM => Ok(DOM),
            ISO_NUM_ECU => Ok(ECU),
            ISO_NUM_EGY => Ok(EGY),
            ISO_NUM_SLV => Ok(SLV),
            ISO_NUM_GNQ => Ok(GNQ),
            ISO_NUM_ERI => Ok(ERI),
            ISO_NUM_EST => Ok(EST),
            ISO_NUM_ETH => Ok(ETH),
            ISO_NUM_FLK => Ok(FLK),
            ISO_NUM_FRO => Ok(FRO),
            ISO_NUM_FJI => Ok(FJI),
            ISO_NUM_FIN => Ok(FIN),
            ISO_NUM_FRA => Ok(FRA),
            ISO_NUM_GUF => Ok(GUF),
            ISO_NUM_PYF => Ok(PYF),
            ISO_NUM_ATF => Ok(ATF),
            ISO_NUM_GAB => Ok(GAB),
            ISO_NUM_GMB => Ok(GMB),
            ISO_NUM_GEO => Ok(GEO),
            ISO_NUM_DEU => Ok(DEU),
            ISO_NUM_GHA => Ok(GHA),
            ISO_NUM_GIB => Ok(GIB),
            ISO_NUM_GRC => Ok(GRC),
            ISO_NUM_GRL => Ok(GRL),
            ISO_NUM_GRD => Ok(GRD),
            ISO_NUM_GLP => Ok(GLP),
            ISO_NUM_GUM => Ok(GUM),
            ISO_NUM_GTM => Ok(GTM),
            ISO_NUM_GGY => Ok(GGY),
            ISO_NUM_GIN => Ok(GIN),
            ISO_NUM_GNB => Ok(GNB),
            ISO_NUM_GUY => Ok(GUY),
            ISO_NUM_HTI => Ok(HTI),
            ISO_NUM_HMD => Ok(HMD),
            ISO_NUM_VAT => Ok(VAT),
            ISO_NUM_HND => Ok(HND),
            ISO_NUM_HKG => Ok(HKG),
            ISO_NUM_HUN => Ok(HUN),
            ISO_NUM_ISL => Ok(ISL),
            ISO_NUM_IND => Ok(IND),
            ISO_NUM_IDN => Ok(IDN),
            ISO_NUM_IRN => Ok(IRN),
            ISO_NUM_IRQ => Ok(IRQ),
            ISO_NUM_IRL => Ok(IRL),
            ISO_NUM_IMN => Ok(IMN),
            ISO_NUM_ISR => Ok(ISR),
            ISO_NUM_ITA => Ok(ITA),
            ISO_NUM_JAM => Ok(JAM),
            ISO_NUM_JPN => Ok(JPN),
            ISO_NUM_JEY => Ok(JEY),
            ISO_NUM_JOR => Ok(JOR),
            ISO_NUM_KAZ => Ok(KAZ),
            ISO_NUM_KEN => Ok(KEN),
            ISO_NUM_KIR => Ok(KIR),
            ISO_NUM_PRK => Ok(PRK),
            ISO_NUM_KOR => Ok(KOR),
            ISO_NUM_KWT => Ok(KWT),
            ISO_NUM_KGZ => Ok(KGZ),
            ISO_NUM_LAO => Ok(LAO),
            ISO_NUM_LVA => Ok(LVA),
            ISO_NUM_LBN => Ok(LBN),
            ISO_NUM_LSO => Ok(LSO),
            ISO_NUM_LBR => Ok(LBR),
            ISO_NUM_LBY => Ok(LBY),
            ISO_NUM_LIE => Ok(LIE),
            ISO_NUM_LTU => Ok(LTU),
            ISO_NUM_LUX => Ok(LUX),
            ISO_NUM_MAC => Ok(MAC),
            ISO_NUM_MKD => Ok(MKD),
            ISO_NUM_MDG => Ok(MDG),
            ISO_NUM_MWI => Ok(MWI),
            ISO_NUM_MYS => Ok(MYS),
            ISO_NUM_MDV => Ok(MDV),
            ISO_NUM_MLI => Ok(MLI),
            ISO_NUM_MLT => Ok(MLT),
            ISO_NUM_MHL => Ok(MHL),
            ISO_NUM_MTQ => Ok(MTQ),
            ISO_NUM_MRT => Ok(MRT),
            ISO_NUM_MUS => Ok(MUS),
            ISO_NUM_MYT => Ok(MYT),
            ISO_NUM_MEX => Ok(MEX),
            ISO_NUM_FSM => Ok(FSM),
            ISO_NUM_MDA => Ok(MDA),
            ISO_NUM_MCO => Ok(MCO),
            ISO_NUM_MNG => Ok(MNG),
            ISO_NUM_MNE => Ok(MNE),
            ISO_NUM_MSR => Ok(MSR),
            ISO_NUM_MAR => Ok(MAR),
            ISO_NUM_MOZ => Ok(MOZ),
            ISO_NUM_MMR => Ok(MMR),
            ISO_NUM_NAM => Ok(NAM),
            ISO_NUM_NRU => Ok(NRU),
            ISO_NUM_NPL => Ok(NPL),
            ISO_NUM_NLD => Ok(NLD),
            ISO_NUM_NCL => Ok(NCL),
            ISO_NUM_NZL => Ok(NZL),
            ISO_NUM_NIC => Ok(NIC),
            ISO_NUM_NER => Ok(NER),
            ISO_NUM_NGA => Ok(NGA),
            ISO_NUM_NIU => Ok(NIU),
            ISO_NUM_NFK => Ok(NFK),
            ISO_NUM_MNP => Ok(MNP),
            ISO_NUM_NOR => Ok(NOR),
            ISO_NUM_OMN => Ok(OMN),
            ISO_NUM_PAK => Ok(PAK),
            ISO_NUM_PLW => Ok(PLW),
            ISO_NUM_PSE => Ok(PSE),
            ISO_NUM_PAN => Ok(PAN),
            ISO_NUM_PNG => Ok(PNG),
            ISO_NUM_PRY => Ok(PRY),
            ISO_NUM_PER => Ok(PER),
            ISO_NUM_PHL => Ok(PHL),
            ISO_NUM_PCN => Ok(PCN),
            ISO_NUM_POL => Ok(POL),
            ISO_NUM_PRT => Ok(PRT),
            ISO_NUM_PRI => Ok(PRI),
            ISO_NUM_QAT => Ok(QAT),
            ISO_NUM_REU => Ok(REU),
            ISO_NUM_ROU => Ok(ROU),
            ISO_NUM_RUS => Ok(RUS),
            ISO_NUM_RWA => Ok(RWA),
            ISO_NUM_BLM => Ok(BLM),
            ISO_NUM_SHN => Ok(SHN),
            ISO_NUM_KNA => Ok(KNA),
            ISO_NUM_LCA => Ok(LCA),
            ISO_NUM_MAF => Ok(MAF),
            ISO_NUM_SPM => Ok(SPM),
            ISO_NUM_VCT => Ok(VCT),
            ISO_NUM_WSM => Ok(WSM),
            ISO_NUM_SMR => Ok(SMR),
            ISO_NUM_STP => Ok(STP),
            ISO_NUM_SAU => Ok(SAU),
            ISO_NUM_SEN => Ok(SEN),
            ISO_NUM_SRB => Ok(SRB),
            ISO_NUM_SYC => Ok(SYC),
            ISO_NUM_SLE => Ok(SLE),
            ISO_NUM_SGP => Ok(SGP),
            ISO_NUM_SXM => Ok(SXM),
            ISO_NUM_SVK => Ok(SVK),
            ISO_NUM_SVN => Ok(SVN),
            ISO_NUM_SLB => Ok(SLB),
            ISO_NUM_SOM => Ok(SOM),
            ISO_NUM_ZAF => Ok(ZAF),
            ISO_NUM_SGS => Ok(SGS),
            ISO_NUM_SSD => Ok(SSD),
            ISO_NUM_ESP => Ok(ESP),
            ISO_NUM_LKA => Ok(LKA),
            ISO_NUM_SDN => Ok(SDN),
            ISO_NUM_SUR => Ok(SUR),
            ISO_NUM_SJM => Ok(SJM),
            ISO_NUM_SWZ => Ok(SWZ),
            ISO_NUM_SWE => Ok(SWE),
            ISO_NUM_CHE => Ok(CHE),
            ISO_NUM_SYR => Ok(SYR),
            ISO_NUM_TWN => Ok(TWN),
            ISO_NUM_TJK => Ok(TJK),
            ISO_NUM_TZA => Ok(TZA),
            ISO_NUM_THA => Ok(THA),
            ISO_NUM_TLS => Ok(TLS),
            ISO_NUM_TGO => Ok(TGO),
            ISO_NUM_TKL => Ok(TKL),
            ISO_NUM_TON => Ok(TON),
            ISO_NUM_TTO => Ok(TTO),
            ISO_NUM_TUN => Ok(TUN),
            ISO_NUM_TUR => Ok(TUR),
            ISO_NUM_TKM => Ok(TKM),
            ISO_NUM_TCA => Ok(TCA),
            ISO_NUM_TUV => Ok(TUV),
            ISO_NUM_UGA => Ok(UGA),
            ISO_NUM_UKR => Ok(UKR),
            ISO_NUM_ARE => Ok(ARE),
            ISO_NUM_GBR => Ok(GBR),
            ISO_NUM_USA => Ok(USA),
            ISO_NUM_UMI => Ok(UMI),
            ISO_NUM_URY => Ok(URY),
            ISO_NUM_UZB => Ok(UZB),
            ISO_NUM_VUT => Ok(VUT),
            ISO_NUM_VEN => Ok(VEN),
            ISO_NUM_VNM => Ok(VNM),
            ISO_NUM_VGB => Ok(VGB),
            ISO_NUM_VIR => Ok(VIR),
            ISO_NUM_WLF => Ok(WLF),
            ISO_NUM_ESH => Ok(ESH),
            ISO_NUM_YEM => Ok(YEM),
            ISO_NUM_ZMB => Ok(ZMB),
            ISO_NUM_ZWE => Ok(ZWE),
            x => Err(CountryCodeParseErr::InvalidID { unknown: x }),
        }
    }

    /// Returns an array of all CountryCode variants, sorted in ascending lexicographic order
    /// by the full name of the corresponding country
    pub fn as_array() -> &'static [CountryCode; NUM_COUNTRY_CODES] {
        &sorted_arrays::CODES_SORTED_DEFAULT
    }

    /// Returns an array of all CountryCode variants, sorted in ascending lexicographic order
    /// by the alpha-2 code for the corresponding country
    pub fn as_array_alpha2() -> &'static [CountryCode; NUM_COUNTRY_CODES] {
        &sorted_arrays::CODES_SORTED_ALPHA2
    }

    /// Returns an iterator over all CountryCode variants, sorted in ascending lexicographic order
    /// by the alpha-3 code for the corresponding country
    pub fn as_array_alpha3() -> &'static [CountryCode; NUM_COUNTRY_CODES] {
        &sorted_arrays::CODES_SORTED_ALPHA3
    }

    /// Returns an iterator over all CountryCode variants, sorted in ascending order
    /// by the numeric code for the corresponding country
    pub fn as_array_numeric() -> &'static [CountryCode; NUM_COUNTRY_CODES] {
        &sorted_arrays::CODES_SORTED_NUMERIC_ID
    }

    /// Returns an iterator over all CountryCode variants, sorted in ascending lexicographic order
    /// by the full name of the corresponding country
    pub fn iter() -> impl Iterator<Item = &'static CountryCode> {
        sorted_arrays::CODES_SORTED_DEFAULT.iter()
    }

    /// Returns an iterator over all CountryCode variants, sorted in ascending lexicographic order
    /// by the alpha-2 code for the corresponding country
    pub fn iter_alpha2() -> impl Iterator<Item = &'static CountryCode> {
        sorted_arrays::CODES_SORTED_ALPHA2.iter()
    }

    /// Returns an iterator over all CountryCode variants, sorted in ascending lexicographic order
    /// by the alpha-3 code for the corresponding country
    pub fn iter_alpha3() -> impl Iterator<Item = &'static CountryCode> {
        sorted_arrays::CODES_SORTED_ALPHA3.iter()
    }

    /// Returns an iterator over all CountryCode variants, sorted in ascending order
    /// by the numeric code for the corresponding country
    pub fn iter_numeric() -> impl Iterator<Item = &'static CountryCode> {
        sorted_arrays::CODES_SORTED_NUMERIC_ID.iter()
    }

    /// Returns the number of unique ISO 3166-1 defined country codes currently supported by this
    /// library.
    pub fn num_country_codes() -> usize {
        NUM_COUNTRY_CODES
    }
}

impl Into<u32> for CountryCode {
    fn into(self) -> u32 {
        self.numeric_id()
    }
}

impl Display for CountryCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        f.write_str(self.name())
    }
}

struct CountryCodeVisitor;

impl Serialize for CountryCode {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
      S: Serializer {
        serializer.collect_str(self.alpha2())
    }
}

impl<'de> Deserialize<'de> for CountryCode {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
      D: Deserializer<'de> {
        deserializer.deserialize_str(CountryCodeVisitor)
    }
}

impl<'de> Visitor<'de> for CountryCodeVisitor {
    type Value = CountryCode;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "an ISO 3166-1 compliant alpha-2 country code")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where
          E: de::Error,
    {
        match CountryCode::for_alpha2_caseless(v) {
            Ok(x) => Ok(x),
            Err(_) => Err(de::Error::invalid_value(de::Unexpected::Str(v), &self)),
        }
    }

    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
        where
          E: de::Error,
    {
        match CountryCode::for_alpha2_caseless(v) {
            Ok(x) => Ok(x),
            Err(_) => Err(de::Error::invalid_value(de::Unexpected::Str(v), &self)),
        }
    }
}
