Skip to content
Snippets Groups Projects
Verified Commit 678279bd authored by jan.hamal.dvorak's avatar jan.hamal.dvorak
Browse files

Get rid of ICU dependency

parent 80caa889
No related branches found
No related tags found
No related merge requests found
......@@ -84,7 +84,6 @@ common common
, resourcet >=1.2 && <1.3
, string-conversions >=0.4 && <0.5
, text >=1.2 && <1.3
, text-icu >=0.7 && <0.8
, time >=1.9 && <1.12
, wai >=3.2 && <3.3
, wai-extra >=3.0 && <3.2
......@@ -114,6 +113,9 @@ library
other-modules:
Paths_hikaru
ghc-options:
-Wunused-packages
test-suite spec
import: common
......
......@@ -17,6 +17,7 @@ module Hikaru.Media
-- * Parsing
, parseMedia
, pMediaList
-- * Matching
, matchMedia
......@@ -24,11 +25,13 @@ module Hikaru.Media
, selectMedia
)
where
import Relude hiding (group, find, head)
import Relude hiding (head, get, many)
import Relude.Unsafe (head)
import Text.ParserCombinators.ReadP
import Data.String.Conversions
import Data.Text.ICU
import Data.Text (toLower)
import Data.List (lookup)
import Data.Char (isControl, isSpace)
-- |
......@@ -41,6 +44,7 @@ where
= Media
{ mediaMainType :: Text
, mediaSubType :: Text
, mediaParams :: [(Text, Text)]
, mediaQuality :: Float
}
deriving (Show, Eq, Ord)
......@@ -65,19 +69,48 @@ where
-- ]
--
parseMedia :: Text -> [Media]
parseMedia = sortWith (negate . mediaQuality)
. mapMaybe build
. mapMaybe (group 0)
. findAll reMedia
parseMedia text = case readP_to_S pMediaList (cs (toLower text)) of
(m, ""):_ -> sortWith (negate . mediaQuality) m
_else -> []
-- |
-- Parser for the media list coded mostly to the RFC 2045.
-- Input is always lowercased and unicode is accepted.
--
pMediaList :: ReadP [Media]
pMediaList = sepBy pMedia pSeparator <* eof
where
build :: Text -> Maybe Media
build t = do
match <- find reParts t
main <- group 1 match
sub <- group 2 match
q <- (readMaybe =<< cs <$> group 3 match) <|> Just 1.0
pMedia = do
mediaMainType <- cs <$> pToken
_ <- char '/'
mediaSubType <- cs <$> pToken
mediaParams <- many pParameter
let mediaQuality = fromMaybe 1.0 do
q <- lookup "q" mediaParams
readMaybe (cs q)
return Media{..}
pParameter = do
_ <- pSpaced $ char ';'
name <- cs <$> pToken
_ <- pSpaced $ char '='
value <- cs <$> pValue
return (name, value)
pSeparator = pSpaced $ char ','
pToken = pSpaced $ many1 (satisfy (not . quote))
pValue = pToken <++ pQuotedStr
pQuotedStr = pSpaced $ pQuoted $ many (pExcept '\\')
return $ Media main sub q
pExcept c = satisfy (c /=)
pSpaced p = skipSpaces *> p <* skipSpaces
pQuoted p = char '"' *> p <* char '"'
quote c = isControl c || isSpace c || c `elem` specials
specials = "()<>@,;:\\\"/[]?=" :: [Char]
-- |
......@@ -135,18 +168,4 @@ where
prod = [(l, r) | l <- ls, r <- rs]
-- |
-- Used to split text into individual media elements.
--
reMedia :: Regex
reMedia = "(?:[^,]|\"(?:[^\"]|\\\")*\")+"
-- |
-- Used to split media element into its individual components.
--
reParts :: Regex
reParts = "([[:alnum:]!#$%&'*+.^_`|~-]+)(?:\\s*/\\s*([[:alnum:]!#$%&'*+.^_`|~-]+))?(?:.*;q\\s*=\\s*([0-9.]+))?"
-- vim:set ft=haskell sw=2 ts=2 et:
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment