haskell-postal 0.2.0.1 → 0.2.1.0
raw patch · 5 files changed
+72/−53 lines, 5 filesdep +hspecPVP ok
version bump matches the API change (PVP)
Dependencies added: hspec
API changes (from Hackage documentation)
Files
- haskell-postal.cabal +9/−4
- src/NLP/Postal.hs +13/−12
- src/main.hs +0/−37
- test/NLP/Postal/PostalSpec.hs +49/−0
- test/Spec.hs +1/−0
haskell-postal.cabal view
@@ -1,5 +1,5 @@ name: haskell-postal-version: 0.2.0.1+version: 0.2.1.0 synopsis: Haskell binding for the libpostal library description: Provides an interface for the libpostal NLP library homepage: https://github.com/netom/haskell-postal#readme@@ -25,9 +25,12 @@ , text >= 1.2 && < 1.3 , inline-c >= 0.6 && < 0.7 -executable haskell-postal- hs-source-dirs: src- main-is: main.hs+test-suite spec+ type: exitcode-stdio-1.0+ hs-source-dirs:+ test+ , src+ main-is: Spec.hs default-language: Haskell2010 pkgconfig-depends: libpostal ghc-options: -Wall@@ -36,8 +39,10 @@ , bytestring >= 0.10 && < 0.11 , text >= 1.2 && < 1.3 , inline-c >= 0.6 && < 0.7+ , hspec >= 2.5 && < 2.6 other-modules: NLP.Postal+ , NLP.Postal.PostalSpec source-repository head type: git
src/NLP/Postal.hs view
@@ -31,6 +31,7 @@ import Data.Monoid ((<>)) import Foreign.C.Types import qualified Language.C.Inline as C+import qualified Language.C.Inline.Unsafe as CU import Language.C.Inline.Context as CX import Foreign.Ptr@@ -59,22 +60,22 @@ -- |Calls libpostal_setup() to set up the library -- Make sure you call this before anything else setup :: IO Int-setup = fromIntegral <$> [C.exp| int { libpostal_setup() } |]+setup = fromIntegral <$> [CU.exp| int { libpostal_setup() } |] -- |Calls libpostal_setup_parser() to set up the address parser -- Call this before trying to parse addresses setupParser :: IO Int-setupParser = fromIntegral <$> [C.exp| int { libpostal_setup_parser() } |]+setupParser = fromIntegral <$> [CU.exp| int { libpostal_setup_parser() } |] -- |Calls libpostal_setup_language_classifier() to set up the classifier -- Call this before doing address normaliation setupLanguageClassifier :: IO Int-setupLanguageClassifier = fromIntegral <$> [C.exp| int { libpostal_setup_language_classifier() } |]+setupLanguageClassifier = fromIntegral <$> [CU.exp| int { libpostal_setup_language_classifier() } |] -- |Returns default parser options -- returned by libpostal_get_address_parser_default_options() getAddressParserDefaultOptions :: IO (Ptr AddressParserOptions)-getAddressParserDefaultOptions = castPtr <$> [C.block|+getAddressParserDefaultOptions = castPtr <$> [CU.block| void * { libpostal_address_parser_options_t options = libpostal_get_address_parser_default_options(); void * hoptions = malloc(sizeof(options));@@ -85,7 +86,7 @@ -- |Returns default normalizer options -- returned by libpostal_get_default_options() getDefaultNormalizeOptions :: IO (Ptr NormalizeOptions)-getDefaultNormalizeOptions = castPtr <$> [C.block|+getDefaultNormalizeOptions = castPtr <$> [CU.block| void * { libpostal_normalize_options_t options = libpostal_get_default_options(); void * hoptions = malloc(sizeof(options));@@ -98,7 +99,7 @@ -- parts as a list of key-value tuples (an association list). parseAddress :: Ptr AddressParserOptions -> T.Text -> IO [(T.Text, T.Text)] parseAddress options address = do- response <- [C.exp| void * { libpostal_parse_address($bs-ptr:bsAddress, * (libpostal_address_parser_options_t *) $(void * castedOptions)) } |]+ response <- [CU.exp| void * { libpostal_parse_address($bs-ptr:bsAddress, * (libpostal_address_parser_options_t *) $(void * castedOptions)) } |] when (response == nullPtr) $ fail "libpostal_parse_address returned NULL a pointer" @@ -133,7 +134,7 @@ , TE.decodeUtf8 $ fromForeignPtr (castForeignPtr compFPtr) 0 (fromIntegral compLen) ) - [C.exp| void { libpostal_address_parser_response_destroy((libpostal_address_parser_response_t *) $(void * response)) } |]+ [CU.exp| void { libpostal_address_parser_response_destroy((libpostal_address_parser_response_t *) $(void * response)) } |] return result @@ -147,7 +148,7 @@ expandAddress :: Ptr NormalizeOptions -> T.Text -> IO [T.Text] expandAddress options address = do (numExpansions, expansions) <- C.withPtr $ \numExpansions ->- [C.exp| char * * { libpostal_expand_address($bs-ptr:bsAddress, * (libpostal_normalize_options_t *) $(void * cOptions), $(size_t * numExpansions) ) } |]+ [CU.exp| char * * { libpostal_expand_address($bs-ptr:bsAddress, * (libpostal_normalize_options_t *) $(void * cOptions), $(size_t * numExpansions) ) } |] -- TODO: this also turns an array of (char *) to a list of Texts. result <- forM [0..numExpansions-1] $ \i -> do@@ -163,7 +164,7 @@ return $ TE.decodeUtf8 $ fromForeignPtr (castForeignPtr xpFPtr) 0 (fromIntegral xpLen) - [C.exp| void { libpostal_expansion_array_destroy($(char * * expansions), $(size_t numExpansions)) } |]+ [CU.exp| void { libpostal_expansion_array_destroy($(char * * expansions), $(size_t numExpansions)) } |] return result @@ -173,12 +174,12 @@ -- |Calls libpostal_teardown_parser() tearDownParser :: IO ()-tearDownParser = [C.exp| void { libpostal_teardown_parser() } |]+tearDownParser = [CU.exp| void { libpostal_teardown_parser() } |] -- |Calls libpostal_teardown_language_classifier() tearDownLanguageClassifier :: IO ()-tearDownLanguageClassifier = [C.exp| void { libpostal_teardown_language_classifier() } |]+tearDownLanguageClassifier = [CU.exp| void { libpostal_teardown_language_classifier() } |] -- |Calls libpostal_teardown() tearDown :: IO ()-tearDown = [C.exp| void { libpostal_teardown() } |]+tearDown = [CU.exp| void { libpostal_teardown() } |]
− src/main.hs
@@ -1,37 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Main where--import Control.Monad-import System.Environment-import System.Exit-import NLP.Postal--import qualified Data.Text as T--main :: IO ()-main = do- args <- getArgs-- when (length args /= 1) $ die "Usage: haskell-postal <address>"-- let address = T.pack $ head args-- putStrLn "Setting up libpostal..."- setup >>= \x -> when (x == 0) $ die "FAIL"-- putStrLn "Setting up the parser..."- setupParser >>= \x -> when (x == 0) $ die "FAIL"-- putStrLn "Setting up the language classifier..."- setupLanguageClassifier >>= \x -> when (x == 0) $ die "FAIL"-- defParserOpts <- getAddressParserDefaultOptions- defNormalizeOptions <- getDefaultNormalizeOptions-- parseAddress defParserOpts address >>= print- expandAddress defNormalizeOptions address >>= print-- tearDownLanguageClassifier- tearDownParser- tearDown
+ test/NLP/Postal/PostalSpec.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE OverloadedStrings #-}++module NLP.Postal.PostalSpec (spec) where++import Test.Hspec+import NLP.Postal+import Control.Monad (forM_)+import Control.Monad.IO.Class (liftIO)+import Data.List (lookup)+import qualified Data.Text as T++spec :: Spec+spec = do+ describe "setup" $ do+ it "general setup runs successfully" $ do+ r <- liftIO setup+ r `shouldBe` 1+ it "parser setup runs successfully" $ do+ r <- liftIO setupParser+ r `shouldBe` 1+ it "language classifier setup runs successfully" $ do+ r <- liftIO setupLanguageClassifier+ r `shouldBe` 1++ describe "expansion" $ do+ it "expands an address correctly" $ do+ defNormalizeOptions <- liftIO getDefaultNormalizeOptions+ r <- liftIO $ expandAddress defNormalizeOptions "11 Wall Street New York, NY"+ forM_ r $ \xp -> T.take 14 xp `shouldBe` "11 wall street"++ describe "parser" $ do+ it "parses an address correctly" $ do+ defParserOpts <- liftIO getAddressParserDefaultOptions+ r <- liftIO $ parseAddress defParserOpts "11 Wall Street New York, NY"+ lookup "house_number" r `shouldBe` Just "11"+ lookup "road" r `shouldBe` Just "wall street"+ lookup "city" r `shouldBe` Just "new york"+ lookup "state" r `shouldBe` Just "ny"++ describe "teardown" $ do+ it "language classifier teardown" $ do+ r <- liftIO tearDownLanguageClassifier+ r `shouldBe` ()+ it "parser teardown" $ do+ r <- liftIO tearDownParser+ r `shouldBe` ()+ it "teardown" $ do+ r <- liftIO tearDown+ r `shouldBe` ()
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}