~alcinnz/hurl

47f9ef33a45545cb312b5aa956da40ac2de2c99e — Adrian Cochrane 4 years ago 6950ae1
Improve error reporting & it's localization
M hurl.cabal => hurl.cabal +2 -2
@@ 10,7 10,7 @@ name:                hurl
-- PVP summary:      +-+------- breaking API changes
--                   | | +----- non-breaking API additions
--                   | | | +--- code changes with no API change
version:             0.1.0.0
version:             1.0.0.0

-- A short (one-line) description of the package.
synopsis:            Haskell URL resolver


@@ 72,7 72,7 @@ library
  exposed-modules:     Network.URI.Charset, Network.URI.Fetch
  
  -- Modules included in this library but not exported.
  other-modules:       Network.URI.Locale
  other-modules:       Network.URI.Locale, Network.URI.Messages, Network.URI.XDG.Ini
  
  -- LANGUAGE extensions used by modules in this package.
  -- other-extensions:    

M src/Network/URI/Charset.hs => src/Network/URI/Charset.hs +13 -9
@@ 6,6 6,7 @@ import           Data.Text (Text)
import           Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as B
import           Data.Text.Encoding
import           Debug.Trace (trace)

-- | If the MIMEtype specifies a charset parameter, apply it.
resolveCharset :: [String] -- ^ The MIMEtype, split by ';'


@@ 20,15 21,18 @@ resolveCharset [] response = ("text/plain", Left "Filetype unspecified")
-- | Decodes bytes according to a charset identified by it's IANA-assigned name(s).
convertCharset "iso-8859-1" = decodeLatin1
convertCharset "latin1" = decodeLatin1
convertCharset "us-ascii" = decodeUtf8
convertCharset "utf-8" = decodeUtf8
convertCharset "utf-16be" = decodeUtf16BE
convertCharset "utf-16le" = decodeUtf16LE
convertCharset "utf-16" = decodeUtf16LE
convertCharset "utf-32be" = decodeUtf32BE
convertCharset "utf-32le" = decodeUtf32LE
convertCharset "utf-32" = decodeUtf32LE
convertCharset _ = \_ -> "Unsupported text encoding!" -- TODO localize? Should I?
convertCharset "us-ascii" = decodeUtf8With replaceChar
convertCharset "utf-8" = decodeUtf8With replaceChar
convertCharset "utf-16be" = decodeUtf16BEWith replaceChar
convertCharset "utf-16le" = decodeUtf16LEWith replaceChar
convertCharset "utf-16" = decodeUtf16LEWith replaceChar
convertCharset "utf-32be" = decodeUtf32BEWith replaceChar
convertCharset "utf-32le" = decodeUtf32LEWith replaceChar
convertCharset "utf-32" = decodeUtf32LEWith replaceChar
convertCharset charset = -- FIXME Is this the best fallback for unsupported charsets?
    trace ("Unsupported text encoding" ++ charset) $ decodeUtf8With replaceChar

replaceChar error _ = trace error $ Just '�'

-- | Lists all charsets supported by convertCharset
charsets :: [Text]

M src/Network/URI/Fetch.hs => src/Network/URI/Fetch.hs +3 -1
@@ 24,6 24,7 @@ import qualified Data.ByteString.Base64 as B64
#endif

import Network.URI.Locale
import Network.URI.Messages

-- | Data shared accross multiple URI requests.
data Session = Session {


@@ 92,7 93,8 @@ fetchURL _ (defaultMIME:_) uri@URI {uriScheme = "data:"} =
        (mime, response) -> return (mime, Left $ Txt.pack response)
#endif

fetchURL _ _ uri = return ("text/plain", Left $ Txt.concat ["Unsupported link type ", Txt.pack $ uriScheme uri])
fetchURL Session {locale = l} _ URI {uriScheme = scheme} =
    return ("text/plain", Left $ Txt.pack $ trans l $ UnsupportedScheme scheme)

#ifdef WITH_DATA_URI
breakOn c (a:as) | c == a = ([], as)

M src/Network/URI/Locale.hs => src/Network/URI/Locale.hs +7 -1
@@ 14,7 14,8 @@ import Data.Char (toLower)
rfc2616Locale :: IO [String]
rfc2616Locale = do
    locales <- forM ["LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG"] lookupEnv
    return $ mapMaybe toRFC2616Lang $ split ':' $ firstJust locales "en_US"
    let locales' = mapMaybe toRFC2616Lang $ split ':' $ firstJust locales "en_US"
    return (locales' ++ [l | l <- extractLangs locales', l `notElem` locales'])

toRFC2616Lang "C" = Nothing
toRFC2616Lang ('C':'.':_) = Nothing


@@ 29,6 30,11 @@ toRFC2616Lang' ('@':_) = []
toRFC2616Lang' (c:cs) = toLower c : toRFC2616Lang' cs
toRFC2616Lang' [] = []

-- Makes sure to include the raw languages, and not just localized variants.
extractLangs (locale:locales) | (lang:_) <- split '-' locale = lang : extractLangs locales
extractLangs (_:locales) = extractLangs locales
extractLangs [] = []

firstJust (Just a:_) _ | a /= "" = a
firstJust (_:maybes) fallback = firstJust maybes fallback
firstJust [] fallback = fallback

A src/Network/URI/Messages.hs => src/Network/URI/Messages.hs +18 -0
@@ 0,0 1,18 @@
-- | Module holding localized error messages to be presented as a response.
--
-- To localize error messages provided by HURL, provide your translations between
-- "BEGIN LOCALIZATION" & "END LOCALIZATION" in this file.
--
-- The lines are formatted:
--    trans ("LANG":_) (KEY) = "TRANSLATION"
-- with uppercase indicating the bits you fill in.
module Network.URI.Messages (trans, Errors(..)) where

--- BEGIN LOCALIZATION
trans ("en":_) (UnsupportedScheme scheme) = "Unsupported protocol " ++ scheme
--- END LOCALIZATION

trans (_:locales) err = trans locales err
trans [] err = trans ["en"] err

data Errors = UnsupportedScheme String