summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE21
-rw-r--r--README.md5
-rw-r--r--Setup.hs2
-rw-r--r--src/Data/StateCodes.hs23
-rw-r--r--src/Data/StateCodes/ISO31662US.hs434
-rw-r--r--state-codes.cabal60
-rw-r--r--test/Data/StateCodesSpec.hs27
-rw-r--r--test/Spec.hs1
8 files changed, 573 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..403b413
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Agustin Camino
+
+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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..50c1805
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# state-codes
+
+[![Build Status](https://travis-ci.org/acamino/state-codes.svg?branch=master)](https://travis-ci.org/acamino/state-codes)
+
+This package provides the ISO 3166-2:US state codes and i18n names.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
index 0000000..9a994af
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Data/StateCodes.hs b/src/Data/StateCodes.hs
new file mode 100644
index 0000000..514e66c
--- /dev/null
+++ b/src/Data/StateCodes.hs
@@ -0,0 +1,23 @@
+-- | Main entry point, exposing all that needs to be
+
+module Data.StateCodes
+ ( StateCode(..)
+ , allNames
+ , stateList
+ , fromMName
+ , fromMText
+ , fromName
+ , fromText
+ , toName
+ , toText
+ ) where
+
+import Control.Arrow ((&&&))
+import Data.Text (Text)
+
+import Data.StateCodes.ISO31662US
+
+-- | List all codes with names
+
+allNames :: [(StateCode, Text)]
+allNames = map (id &&& toName) $ enumFrom minBound
diff --git a/src/Data/StateCodes/ISO31662US.hs b/src/Data/StateCodes/ISO31662US.hs
new file mode 100644
index 0000000..964e618
--- /dev/null
+++ b/src/Data/StateCodes/ISO31662US.hs
@@ -0,0 +1,434 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternGuards #-}
+
+-- | This file is generated from the Wikipedia page
+-- <https://en.wikipedia.org/wiki/ISO_3166-2:US>
+
+module Data.StateCodes.ISO31662US
+ ( StateCode(..)
+ , stateList
+ , fromMName
+ , fromMText
+ , fromName
+ , fromText
+ , toName
+ , toText
+ ) where
+
+import Control.Applicative (pure)
+import Data.Aeson
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Typeable
+import Text.Shakespeare.I18N
+
+data StateCode = AL
+ | AK
+ | AZ
+ | AR
+ | CA
+ | CO
+ | CT
+ | DE
+ | FL
+ | GA
+ | HI
+ | ID
+ | IL
+ | IN
+ | IA
+ | KS
+ | KY
+ | LA
+ | ME
+ | MD
+ | MA
+ | MI
+ | MN
+ | MS
+ | MO
+ | MT
+ | NE
+ | NV
+ | NH
+ | NJ
+ | NM
+ | NY
+ | NC
+ | ND
+ | OH
+ | OK
+ | OR
+ | PA
+ | RI
+ | SC
+ | SD
+ | TN
+ | TX
+ | UT
+ | VT
+ | VA
+ | WA
+ | WV
+ | WI
+ | WY
+ | DC
+ | AS
+ | GU
+ | MP
+ | PR
+ | UM
+ | VI
+ deriving (Bounded, Eq, Enum, Show, Read, Ord, Typeable)
+
+
+-- | Maybe get the StateCode from the text code.
+
+fromMText :: Text -> Maybe StateCode
+fromMText "AL" = Just AL
+fromMText "AK" = Just AK
+fromMText "AZ" = Just AZ
+fromMText "AR" = Just AR
+fromMText "CA" = Just CA
+fromMText "CO" = Just CO
+fromMText "CT" = Just CT
+fromMText "DE" = Just DE
+fromMText "FL" = Just FL
+fromMText "GA" = Just GA
+fromMText "HI" = Just HI
+fromMText "ID" = Just ID
+fromMText "IL" = Just IL
+fromMText "IN" = Just IN
+fromMText "IA" = Just IA
+fromMText "KS" = Just KS
+fromMText "KY" = Just KY
+fromMText "LA" = Just LA
+fromMText "ME" = Just ME
+fromMText "MD" = Just MD
+fromMText "MA" = Just MA
+fromMText "MI" = Just MI
+fromMText "MN" = Just MN
+fromMText "MS" = Just MS
+fromMText "MO" = Just MO
+fromMText "MT" = Just MT
+fromMText "NE" = Just NE
+fromMText "NV" = Just NV
+fromMText "NH" = Just NH
+fromMText "NJ" = Just NJ
+fromMText "NM" = Just NM
+fromMText "NY" = Just NY
+fromMText "NC" = Just NC
+fromMText "ND" = Just ND
+fromMText "OH" = Just OH
+fromMText "OK" = Just OK
+fromMText "OR" = Just OR
+fromMText "PA" = Just PA
+fromMText "RI" = Just RI
+fromMText "SC" = Just SC
+fromMText "SD" = Just SD
+fromMText "TN" = Just TN
+fromMText "TX" = Just TX
+fromMText "UT" = Just UT
+fromMText "VT" = Just VT
+fromMText "VA" = Just VA
+fromMText "WA" = Just WA
+fromMText "WV" = Just WV
+fromMText "WI" = Just WI
+fromMText "WY" = Just WY
+fromMText "DC" = Just DC
+fromMText "AS" = Just AS
+fromMText "GU" = Just GU
+fromMText "MP" = Just MP
+fromMText "PR" = Just PR
+fromMText "UM" = Just UM
+fromMText "VI" = Just VI
+fromMText _ = Nothing
+
+
+-- | Get the StateCode from the text code. Errors if the code is unknown
+
+fromText :: Text -> StateCode
+fromText c = case fromMText c of
+ Just sc -> sc
+ _ -> error $ "fromText: Unknown state code:" ++ T.unpack c
+
+
+-- | Get the code as text
+
+toText :: StateCode -> Text
+toText AL = "AL"
+toText AK = "AK"
+toText AZ = "AZ"
+toText AR = "AR"
+toText CA = "CA"
+toText CO = "CO"
+toText CT = "CT"
+toText DE = "DE"
+toText FL = "FL"
+toText GA = "GA"
+toText HI = "HI"
+toText ID = "ID"
+toText IL = "IL"
+toText IN = "IN"
+toText IA = "IA"
+toText KS = "KS"
+toText KY = "KY"
+toText LA = "LA"
+toText ME = "ME"
+toText MD = "MD"
+toText MA = "MA"
+toText MI = "MI"
+toText MN = "MN"
+toText MS = "MS"
+toText MO = "MO"
+toText MT = "MT"
+toText NE = "NE"
+toText NV = "NV"
+toText NH = "NH"
+toText NJ = "NJ"
+toText NM = "NM"
+toText NY = "NY"
+toText NC = "NC"
+toText ND = "ND"
+toText OH = "OH"
+toText OK = "OK"
+toText OR = "OR"
+toText PA = "PA"
+toText RI = "RI"
+toText SC = "SC"
+toText SD = "SD"
+toText TN = "TN"
+toText TX = "TX"
+toText UT = "UT"
+toText VT = "VT"
+toText VA = "VA"
+toText WA = "WA"
+toText WV = "WV"
+toText WI = "WI"
+toText WY = "WY"
+toText DC = "DC"
+toText AS = "AS"
+toText GU = "GU"
+toText MP = "MP"
+toText PR = "PR"
+toText UM = "UM"
+toText VI = "VI"
+
+
+-- | Maybe get the code from the user readable name
+
+fromMName :: Text -> Maybe StateCode
+fromMName "Alabama" = Just AL
+fromMName "Alaska" = Just AK
+fromMName "Arizona" = Just AZ
+fromMName "Arkansas" = Just AR
+fromMName "California" = Just CA
+fromMName "Colorado" = Just CO
+fromMName "Connecticut" = Just CT
+fromMName "Delaware" = Just DE
+fromMName "Florida" = Just FL
+fromMName "Georgia" = Just GA
+fromMName "Hawaii" = Just HI
+fromMName "Idaho" = Just ID
+fromMName "Illinois" = Just IL
+fromMName "Indiana" = Just IN
+fromMName "Iowa" = Just IA
+fromMName "Kansas" = Just KS
+fromMName "Kentucky" = Just KY
+fromMName "Louisiana" = Just LA
+fromMName "Maine" = Just ME
+fromMName "Maryland" = Just MD
+fromMName "Massachusetts" = Just MA
+fromMName "Michigan" = Just MI
+fromMName "Minnesota" = Just MN
+fromMName "Mississippi" = Just MS
+fromMName "Missouri" = Just MO
+fromMName "Montana" = Just MT
+fromMName "Nebraska" = Just NE
+fromMName "Nevada" = Just NV
+fromMName "New Hampshire" = Just NH
+fromMName "New Jersey" = Just NJ
+fromMName "New Mexico" = Just NM
+fromMName "New York" = Just NY
+fromMName "North Carolina" = Just NC
+fromMName "North Dakota" = Just ND
+fromMName "Ohio" = Just OH
+fromMName "Oklahoma" = Just OK
+fromMName "Oregon" = Just OR
+fromMName "Pennsylvania" = Just PA
+fromMName "Rhode Island" = Just RI
+fromMName "South Carolina" = Just SC
+fromMName "South Dakota" = Just SD
+fromMName "Tennessee" = Just TN
+fromMName "Texas" = Just TX
+fromMName "Utah" = Just UT
+fromMName "Vermont" = Just VT
+fromMName "Virginia" = Just VA
+fromMName "Washington" = Just WA
+fromMName "West Virginia" = Just WV
+fromMName "Wisconsin" = Just WI
+fromMName "Wyoming" = Just WY
+fromMName "District of Columbia" = Just DC
+fromMName "American Samoa" = Just AS
+fromMName "Guam" = Just GU
+fromMName "Northern Mariana Islands" = Just MP
+fromMName "Puerto Rico" = Just PR
+fromMName "United States Minor Outlying Islands" = Just UM
+fromMName "Virgin Islands, U.S." = Just VI
+fromMName _ = Nothing
+
+
+-- | Get the StateCode from the user readable name. Errors if the name is unknown
+
+fromName:: Text -> StateCode
+fromName s = case fromMName s of
+ Just sc -> sc
+ _ -> error $ "fromName: Unknown state code:" ++ T.unpack s
+
+
+-- | Get the user readable name
+
+toName :: StateCode -> Text
+toName AL = "Alabama"
+toName AK = "Alaska"
+toName AZ = "Arizona"
+toName AR = "Arkansas"
+toName CA = "California"
+toName CO = "Colorado"
+toName CT = "Connecticut"
+toName DE = "Delaware"
+toName FL = "Florida"
+toName GA = "Georgia"
+toName HI = "Hawaii"
+toName ID = "Idaho"
+toName IL = "Illinois"
+toName IN = "Indiana"
+toName IA = "Iowa"
+toName KS = "Kansas"
+toName KY = "Kentucky"
+toName LA = "Louisiana"
+toName ME = "Maine"
+toName MD = "Maryland"
+toName MA = "Massachusetts"
+toName MI = "Michigan"
+toName MN = "Minnesota"
+toName MS = "Mississippi"
+toName MO = "Missouri"
+toName MT = "Montana"
+toName NE = "Nebraska"
+toName NV = "Nevada"
+toName NH = "New Hampshire"
+toName NJ = "New Jersey"
+toName NM = "New Mexico"
+toName NY = "New York"
+toName NC = "North Carolina"
+toName ND = "North Dakota"
+toName OH = "Ohio"
+toName OK = "Oklahoma"
+toName OR = "Oregon"
+toName PA = "Pennsylvania"
+toName RI = "Rhode Island"
+toName SC = "South Carolina"
+toName SD = "South Dakota"
+toName TN = "Tennessee"
+toName TX = "Texas"
+toName UT = "Utah"
+toName VT = "Vermont"
+toName VA = "Virginia"
+toName WA = "Washington"
+toName WV = "West Virginia"
+toName WI = "Wisconsin"
+toName WY = "Wyoming"
+toName DC = "District of Columbia"
+toName AS = "American Samoa"
+toName GU = "Guam"
+toName MP = "Northern Mariana Islands"
+toName PR = "Puerto Rico"
+toName UM = "United States Minor Outlying Islands"
+toName VI = "Virgin Islands, U.S."
+
+
+-- | List of names sorted by alphabetical order, with state code
+-- this is ready to be used in a yesod selectField, for example
+
+stateList :: [(T.Text, StateCode)]
+stateList = [ ("Alabama", AL)
+ , ("Alaska", AK)
+ , ("Arizona", AZ)
+ , ("Arkansas", AR)
+ , ("California", CA)
+ , ("Colorado", CO)
+ , ("Connecticut", CT)
+ , ("Delaware", DE)
+ , ("Florida", FL)
+ , ("Georgia", GA)
+ , ("Hawaii", HI)
+ , ("Idaho", ID)
+ , ("Illinois", IL)
+ , ("Indiana", IN)
+ , ("Iowa", IA)
+ , ("Kansas", KS)
+ , ("Kentucky", KY)
+ , ("Louisiana", LA)
+ , ("Maine", ME)
+ , ("Maryland", MD)
+ , ("Massachusetts", MA)
+ , ("Michigan", MI)
+ , ("Minnesota", MN)
+ , ("Mississippi", MS)
+ , ("Missouri", MO)
+ , ("Montana", MT)
+ , ("Nebraska", NE)
+ , ("Nevada", NV)
+ , ("New Hampshire", NH)
+ , ("New Jersey", NJ)
+ , ("New Mexico", NM)
+ , ("New York", NY)
+ , ("North Carolina", NC)
+ , ("North Dakota", ND)
+ , ("Ohio", OH)
+ , ("Oklahoma", OK)
+ , ("Oregon", OR)
+ , ("Pennsylvania", PA)
+ , ("Rhode Island", RI)
+ , ("South Carolina", SC)
+ , ("South Dakota", SD)
+ , ("Tennessee", TN)
+ , ("Texas", TX)
+ , ("Utah", UT)
+ , ("Vermont", VT)
+ , ("Virginia", VA)
+ , ("Washington", WA)
+ , ("West Virginia", WV)
+ , ("Wisconsin", WI)
+ , ("Wyoming", WY)
+ , ("District of Columbia", DC)
+ , ("American Samoa", AS)
+ , ("Guam", GU)
+ , ("Northern Mariana Islands", MP)
+ , ("Puerto Rico", PR)
+ , ("United States Minor Outlying Islands", UM)
+ , ("Virgin Islands, U.S.", VI)
+ ]
+
+
+-- | To JSON: as a simple string
+
+instance ToJSON StateCode where
+ toJSON = toJSON . toText
+
+
+-- | From JSON: as a simple string
+
+instance FromJSON StateCode where
+ parseJSON (String s)
+ | Just a <- fromMText s = pure a
+ parseJSON _ = fail "StateCode"
+
+
+-- | Show user readable name, in English (ignoring locale for now)
+
+instance RenderMessage master StateCode where
+ renderMessage _ _ = toName
diff --git a/state-codes.cabal b/state-codes.cabal
new file mode 100644
index 0000000..2c843db
--- /dev/null
+++ b/state-codes.cabal
@@ -0,0 +1,60 @@
+name: state-codes
+version: 0.1.0
+synopsis: ISO 3166-2:US state codes and i18n names
+description: This package provides the ISO 3166-2:US state codes and i18n names
+homepage: https://github.com/acamino/state-codes#README
+license: MIT
+license-file: LICENSE
+author: Agustin Camino
+maintainer: agustin.camino@gmail.com
+copyright: 2017 Agustin Camino
+category: Data
+build-type: Simple
+cabal-version: >=1.10
+extra-source-files: README.md
+
+
+flag dev
+ description: Turn on development settings
+ manual: True
+ default: False
+
+
+source-repository head
+ type: git
+ location: https://github.com/acamino/state-codes.git
+
+
+library
+ hs-source-dirs: src
+ build-depends:
+ base >= 4.7 && < 5
+ , text
+ , aeson
+ , shakespeare
+ if flag(dev)
+ ghc-options: -Wall -Werror
+ else
+ ghc-options: -O2 -Wall
+ other-modules: Data.StateCodes.ISO31662US
+ exposed-modules: Data.StateCodes
+ default-language: Haskell2010
+
+test-suite state-codes-test
+ main-is: Spec.hs
+ type: exitcode-stdio-1.0
+ hs-source-dirs: test
+ other-modules: Data.StateCodesSpec
+
+ build-depends: base >= 4.7 && < 5.0
+ , aeson
+ , hspec
+ , QuickCheck
+ , state-codes
+ , text
+
+ if flag(dev)
+ ghc-options: -Wall -Werror
+ else
+ ghc-options: -O2 -Wall
+ default-language: Haskell2010
diff --git a/test/Data/StateCodesSpec.hs b/test/Data/StateCodesSpec.hs
new file mode 100644
index 0000000..9f484a3
--- /dev/null
+++ b/test/Data/StateCodesSpec.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# OPTIONS -fno-warn-orphans #-}
+
+module Data.StateCodesSpec where
+
+import Data.Aeson
+import qualified Data.Aeson as A
+import Test.Hspec
+import Test.Hspec.QuickCheck
+import Test.QuickCheck
+
+import Data.StateCodes
+
+instance Arbitrary StateCode where
+ arbitrary = elements [minBound ..]
+
+
+spec :: Spec
+spec = do
+ prop "fromName . toName" $ forAll arbitrary $ \code ->
+ (fromName . toName) code == code
+
+ prop "fromText . toText" $ forAll arbitrary $ \code ->
+ (fromText . toText) code == code
+
+ prop "fromJSON . toJSON" $ forAll (arbitrary :: Gen StateCode)$ \code ->
+ (fromJSON . toJSON) code == A.Success code
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
index 0000000..a824f8c
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}