packages feed

iconv-typed (empty) → 0.1.0.0

raw patch · 8 files changed

+278/−0 lines, 8 filesdep +basedep +bytestringdep +iconvsetup-changed

Dependencies added: base, bytestring, iconv, iconv-typed, shelly, template-haskell, text

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ iconv-typed.cabal view
@@ -0,0 +1,79 @@+name:                iconv-typed+version:             0.1.0.0+synopsis:            Type safe iconv wrapper+homepage:            https://github.com/adinapoli/iconv-typed#readme+license:             BSD3+license-file:        LICENSE+author:              Alfredo Di Napoli+maintainer:          alfredo.dinapoli@gmail.com+copyright:           2016 Alfredo Di Napoli+category:            Web+build-type:          Simple+cabal-version:       >=1.10++description:+  [iconv-typed]+  .+  An experiment in bringing type safety to the <http://hackage.haskell.org/package/iconv iconv> package.+  .+  [Usage Example]+  This is _almost_ a drop-in replacement. Compare the original code from `iconv`:+  .+  > {-# LANGUAGE KindSignatures #-}+  > {-# LANGUAGE DataKinds #-}+  > {-# LANGUAGE OverloadedStrings #-}+  > module Main where+  >+  > import Codec.Text.IConv+  >+  > main :: IO ()+  > main = print $ convert "UTF-8" "LATIN1" "hello"+  .+  With the equivalent in `iconv-typed`:+  .+  > {-# LANGUAGE KindSignatures #-}+  > {-# LANGUAGE DataKinds #-}+  > {-# LANGUAGE OverloadedStrings #-}+  > module Main where+  >+  > import Codec.Text.IConv.Typed+  >+  > main :: IO ()+  > main = print $ convert (E :: E "UTF-8") (E :: E "LATIN1") "hello"+  .+  As a result, this code will compile and run only if the passed encoding resolves to a supported+  encoding (as retrieved at compile time by calling `iconv -l`). For example, the following won't compile:+  .+  > main = print $ convert (E :: E "UFT-8") (E :: E "LATIN1") "hello"+  .+  As `UFT` is mispelled.++library+  hs-source-dirs:      src+  exposed-modules:     Codec.Text.IConv.Typed+                       Codec.Text.IConv.Typed.TH+  build-depends:       base >= 4.7 && < 5,+                       iconv < 0.5,+                       shelly < 1.8.0.0,+                       text < 1.4.0.0,+                       template-haskell < 3.0.0.0,+                       bytestring+  default-language:    Haskell2010+  ghc-options:         -Wall+  if os(darwin)+    other-modules:     Codec.Text.IConv.Typed.MacOSX+  else+    other-modules:     Codec.Text.IConv.Typed.Unix++test-suite iconv-typed-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , iconv-typed+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/adinapoli/iconv-typed
+ src/Codec/Text/IConv/Typed.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE KindSignatures #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+module Codec.Text.IConv.Typed+  ( E(..)+  , ValidEncoding+  , convert+  , convertFuzzy+  , convertStrictly+  , convertLazily+  -- * Handy re-exports+  , I.reportConversionError+  , I.Fuzzy(..)+  , I.ConversionError(..)+  , I.Span(..)+  ) where++import qualified Codec.Text.IConv as I+import           Codec.Text.IConv.Typed.TH+import           Data.ByteString.Lazy+import GHC.TypeLits++$(generateEncodings)++--------------------------------------------------------------------------------+convert :: ( KnownSymbol k1+            , KnownSymbol k2+            , ValidEncoding k1 ~ 'True+            , ValidEncoding k2 ~ 'True+            )+         => E k1       -- ^ Name of input string encoding+         -> E k2       -- ^ Name of output string encoding+         -> ByteString -- ^ Input text+         -> ByteString -- ^ Output text+convert e1 e2 input = I.convert (reifyEncoding e1) (reifyEncoding e2) input++--------------------------------------------------------------------------------+convertFuzzy :: ( KnownSymbol k1+                , KnownSymbol k2+                , ValidEncoding k1 ~ 'True+                , ValidEncoding k2 ~ 'True+                )+             => I.Fuzzy -- ^ Whether to try and transliterate or+                        -- discard characters with no direct conversion+             -> E k1    -- ^ Name of input string encoding+             -> E k2    -- ^ Name of output string encoding+             -> ByteString    -- ^ Input text+             -> ByteString    -- ^ Output text+convertFuzzy fuzzy fromEncoding toEncoding input =+  I.convertFuzzy fuzzy (reifyEncoding fromEncoding) (reifyEncoding toEncoding) input++--------------------------------------------------------------------------------+convertStrictly :: ( KnownSymbol k1+                   , KnownSymbol k2+                   , ValidEncoding k1 ~ 'True+                   , ValidEncoding k2 ~ 'True+                   )+                => E k1                                -- ^ Name of input string encoding+                -> E k2                                -- ^ Name of output string encoding+                -> ByteString                          -- ^ Input text+                -> Either ByteString I.ConversionError -- ^ Output text or conversion error+convertStrictly fromEncoding toEncoding input =+  I.convertStrictly (reifyEncoding fromEncoding) (reifyEncoding toEncoding) input++--------------------------------------------------------------------------------+convertLazily :: ( KnownSymbol k1+                 , KnownSymbol k2+                 , ValidEncoding k1 ~ 'True+                 , ValidEncoding k2 ~ 'True+                 )+              => E k1  -- ^ Name of input string encoding+              -> E k2  -- ^ Name of output string encoding+              -> ByteString  -- ^ Input text+              -> [I.Span]        -- ^ Output text spans+convertLazily fromEncoding toEncoding input = I.convertLazily (reifyEncoding fromEncoding) (reifyEncoding toEncoding) input
+ src/Codec/Text/IConv/Typed/MacOSX.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE OverloadedStrings #-}+module Codec.Text.IConv.Typed.MacOSX+  ( getAvailableEncodings+  ) where++import Codec.Text.IConv (EncodingName)+import System.IO.Unsafe (unsafePerformIO)+import qualified Data.Text as T+import Shelly++getAvailableEncodings :: [EncodingName]+getAvailableEncodings = unsafePerformIO $ shelly $ silently $ escaping False $ do+  map T.unpack . mconcat . map T.words . T.lines . T.strip <$> run "iconv" ["-l"]+{-# NOINLINE getAvailableEncodings #-}
+ src/Codec/Text/IConv/Typed/TH.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE CPP #-}+module Codec.Text.IConv.Typed.TH where++#if defined darwin_HOST_OS+import           Codec.Text.IConv.Typed.MacOSX+#else+import           Codec.Text.IConv.Typed.Unix+#endif++import           Codec.Text.IConv+import           Data.List (foldl')+import           Data.Maybe+import qualified Data.Text as T+import           GHC.TypeLits+import           Language.Haskell.TH+import           Text.Read++data E (k :: Symbol) = E++reifyEncoding :: KnownSymbol k => E k -> String+reifyEncoding = symbolVal++filterNumericEncoding :: [EncodingName] -> [EncodingName]+filterNumericEncoding = filter (not . numerical)+  where+    numerical x = isJust (readMaybe x :: Maybe Int)++--------------------------------------------------------------------------------+replacementRules :: [(T.Text, T.Text)]+replacementRules = [ ("-", "__")+                   , (".", "____")+                   , (":", "___")+                   ]++--------------------------------------------------------------------------------+applyRule :: T.Text -> (T.Text, T.Text) -> T.Text+applyRule t (input, output) = T.replace input output t++--------------------------------------------------------------------------------+convertName :: EncodingName -> EncodingName+convertName = T.unpack . (\t -> foldl' applyRule t replacementRules) . T.pack++-- closedTypeFamilyD :: Name -> [TyVarBndr] -> FamilyResultSig -> Maybe InjectivityAnn -> [TySynEqnQ] -> DecQ+++--------------------------------------------------------------------------------+generateEncodings :: Q [Dec]+generateEncodings = do+  let encs   = getAvailableEncodings+  let k      = mkName "k"+  let symbol = mkName "Symbol"+  let validEncoding = mkName "ValidEncoding"+  let bool = mkName "Bool"+  let instances = flip map encs $ \eName -> do+        return $ TySynEqn [LitT (StrTyLit eName)] (PromotedT (mkName "True"))+  (: []) <$> closedTypeFamilyD validEncoding [KindedTV k (ConT symbol)] (KindSig (ConT bool)) Nothing instances
+ src/Codec/Text/IConv/Typed/Unix.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE OverloadedStrings #-}+module Codec.Text.IConv.Typed.Unix+  ( getAvailableEncodings+  ) where++import Codec.Text.IConv (EncodingName)+import System.IO.Unsafe (unsafePerformIO)+import qualified Data.Text as T+import Shelly++getAvailableEncodings :: [EncodingName]+getAvailableEncodings = unsafePerformIO $ shelly $ silently $ escaping False $ do+  map T.unpack . T.splitOn "," . T.strip <$> run "iconv" ["-l"]+{-# NOINLINE getAvailableEncodings #-}
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"