(module country-codes mzscheme
(require (lib "contract.ss")
(lib "etc.ss")
(lib "list.ss"))
(provide/contract [country-codes (list-immutableof string?)]
[country-code? (string? . -> . boolean?)])
(define iso3166-text #<<EOF
AFGHANISTANĂ…LAND ISLANDSALBANIAALGERIAAMERICAN SAMOAANDORRAANGOLAANGUILLAANTARCTICAANTIGUA AND BARBUDAARGENTINAARMENIAARUBAAUSTRALIAAUSTRIAAZERBAIJANBAHAMASBAHRAINBANGLADESHBARBADOSBELARUSBELGIUMBELIZEBENINBERMUDABHUTANBOLIVIABOSNIA AND HERZEGOVINABOTSWANABOUVET ISLANDBRAZILBRITISH INDIAN OCEAN TERRITORYBRUNEI DARUSSALAMBULGARIABURKINA FASOBURUNDICAMBODIACAMEROONCANADACAPE VERDECAYMAN ISLANDSCENTRAL AFRICAN REPUBLICCHADCHILECHINACHRISTMAS ISLANDCOCOS (KEELING) ISLANDSCOLOMBIACOMOROSCONGOCONGO, THE DEMOCRATIC REPUBLIC OF THECOOK ISLANDSCOSTA RICACOTE D'IVOIRECROATIACUBACYPRUSCZECH REPUBLICDENMARKDJIBOUTIDOMINICADOMINICAN REPUBLICECUADOREGYPTEL SALVADOREQUATORIAL GUINEAERITREAESTONIAETHIOPIAFALKLAND ISLANDS (MALVINAS)FAROE ISLANDSFIJIFINLANDFRANCEFRENCH GUIANAFRENCH POLYNESIAFRENCH SOUTHERN TERRITORIESGABONGAMBIAGEORGIAGERMANYGHANAGIBRALTARGREECEGREENLANDGRENADAGUADELOUPEGUAMGUATEMALAGUERNSEYGUINEAGUINEA-BISSAUGUYANAHAITIHEARD ISLAND AND MCDONALD ISLANDSHOLY SEE (VATICAN CITY STATE)HONDURASHONG KONGHUNGARYICELANDINDIAINDONESIAIRAN, ISLAMIC REPUBLIC OFIRAQIRELANDISLE OF MANISRAELITALYJAMAICAJAPANJERSEYJORDANKAZAKHSTANKENYAKIRIBATIKOREA, DEMOCRATIC PEOPLE'S REPUBLIC OFKOREA, REPUBLIC OFKUWAITKYRGYZSTANLAO PEOPLE'S DEMOCRATIC REPUBLICLATVIALEBANONLESOTHOLIBERIALIBYAN ARAB JAMAHIRIYALIECHTENSTEINLITHUANIALUXEMBOURGMACAOMACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFMADAGASCARMALAWIMALAYSIAMALDIVESMALIMALTAMARSHALL ISLANDSMARTINIQUEMAURITANIAMAURITIUSMAYOTTEMEXICOMICRONESIA, FEDERATED STATES OFMOLDOVA, REPUBLIC OFMONACOMONGOLIAMONTENEGROMONTSERRATMOROCCOMOZAMBIQUEMYANMARNAMIBIANAURUNEPALNETHERLANDSNETHERLANDS ANTILLESNEW CALEDONIANEW ZEALANDNICARAGUANIGERNIGERIANIUENORFOLK ISLANDNORTHERN MARIANA ISLANDSNORWAYOMANPAKISTANPALAUPALESTINIAN TERRITORY, OCCUPIEDPANAMAPAPUA NEW GUINEAPARAGUAYPERUPHILIPPINESPITCAIRNPOLANDPORTUGALPUERTO RICOQATARREUNIONROMANIARUSSIAN FEDERATIONRWANDASAINT HELENASAINT KITTS AND NEVISSAINT LUCIASAINT PIERRE AND MIQUELONSAINT VINCENT AND THE GRENADINESSAMOASAN MARINOSAO TOME AND PRINCIPESAUDI ARABIASENEGALSERBIASEYCHELLESSIERRA LEONESINGAPORESLOVAKIASLOVENIASOLOMON ISLANDSSOMALIASOUTH AFRICASOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDSSPAINSRI LANKASUDANSURINAMESVALBARD AND JAN MAYENSWAZILANDSWEDENSWITZERLANDSYRIAN ARAB REPUBLICTAIWAN, PROVINCE OF CHINATAJIKISTANTANZANIA, UNITED REPUBLIC OFTHAILANDTIMOR-LESTETOGOTOKELAUTONGATRINIDAD AND TOBAGOTUNISIATURKEYTURKMENISTANTURKS AND CAICOS ISLANDSTUVALUUGANDAUKRAINEUNITED ARAB EMIRATESUNITED KINGDOMUNITED STATESUNITED STATES MINOR OUTLYING ISLANDSURUGUAYUZBEKISTANVANUATUVENEZUELAVIET NAMVIRGIN ISLANDS, BRITISHVIRGIN ISLANDS, U.S.WALLIS AND FUTUNAWESTERN SAHARAYEMENZAMBIAZIMBABWEEOF
)
(define ht (make-hash-table 'equal))
(let loop ([i 0])
(cond [(regexp-match-positions #rx"([^;\n]+);([A-Z][A-Z])" iso3166-text i)
=>
(lambda (matches)
(let ([country (substring iso3166-text
(car (second matches))
(cdr (second matches)))]
[code (substring iso3166-text
(car (third matches))
(cdr (third matches)))])
(hash-table-put! ht code country)
(loop (cdr (car matches)))))]))
(define country-codes
(foldr cons-immutable empty (hash-table-map ht (lambda (k v) k))))
(define (lookup a-name)
(hash-table-get
ht a-name
(lambda ()
(and (= (string-length a-name) 2)
(hash-table-get ht
(string (char-upcase (string-ref a-name 0))
(char-upcase (string-ref a-name 1)))
#f)))))
(define (country-code? a-name)
(and (lookup a-name) #t))
(define (country-code->name a-code)
(lookup a-code))
(provide/contract [country-code->name (string? . -> . (or/c string? false/c))]))