From fc74d2df894a0aad13811822cdfcd01200bc1e1b Mon Sep 17 00:00:00 2001 From: Jon Kristensen Date: Sat, 21 Apr 2012 19:18:43 +0200 Subject: [PATCH 1/3] recommitted version functions, rewritten to work with Text and attoparsec --- src/Network/XMPP/Utilities.hs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Network/XMPP/Utilities.hs b/src/Network/XMPP/Utilities.hs index 794fe0f..7841698 100644 --- a/src/Network/XMPP/Utilities.hs +++ b/src/Network/XMPP/Utilities.hs @@ -15,6 +15,7 @@ import Control.Monad.STM import Control.Concurrent.STM.TVar import Prelude +import qualified Data.Attoparsec.Text as AP import qualified Data.Text as Text @@ -60,4 +61,26 @@ idGenerator prefix = atomically $ do -- Characters allowed in IDs. repertoire :: String - repertoire = ['a'..'z'] \ No newline at end of file + repertoire = ['a'..'z'] + + +-- Converts a "." numeric version number to a @Version@ object. +versionFromString :: Text.Text -> Maybe Version +versionFromString s = case AP.parseOnly versionParser s of + Right version -> Just version + Left _ -> Nothing + + +-- Constructs a "Version" based on the major and minor version numbers. +versionFromNumbers :: Integer -> Integer -> Version +versionFromNumbers major minor = Version major minor + + +-- Read numbers, a dot, more numbers, and end-of-file. +versionParser :: AP.Parser Version +versionParser = do + major <- AP.many1 AP.digit + AP.skip (\ c -> c == '.') + minor <- AP.many1 AP.digit + AP.endOfInput + return $ Version (read major) (read minor) \ No newline at end of file From d33f32d5cc06179e1367214100bb5e39ea4c02bf Mon Sep 17 00:00:00 2001 From: Jon Kristensen Date: Sat, 21 Apr 2012 19:23:48 +0200 Subject: [PATCH 2/3] removed head and tail --- src/Network/XMPP/Utilities.hs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Network/XMPP/Utilities.hs b/src/Network/XMPP/Utilities.hs index 7841698..039924a 100644 --- a/src/Network/XMPP/Utilities.hs +++ b/src/Network/XMPP/Utilities.hs @@ -38,8 +38,11 @@ idGenerator prefix = atomically $ do next :: TVar [Text.Text] -> IO Text.Text next tvar = atomically $ do list <- readTVar tvar - writeTVar tvar $ tail list - return $ head list + case list of + [] -> error "empty list in Utilities.hs" + (x:xs) -> do + writeTVar tvar xs + return x -- Generates an infinite and predictable list of IDs, all beginning with the -- provided prefix. From 6b9ebabc0179dbde99108b2635dd5f0e4895bc23 Mon Sep 17 00:00:00 2001 From: Jon Kristensen Date: Sat, 21 Apr 2012 20:38:31 +0200 Subject: [PATCH 3/3] added rewritten langtag functions using Text and attoparsec --- src/Network/XMPP/Utilities.hs | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Network/XMPP/Utilities.hs b/src/Network/XMPP/Utilities.hs index 039924a..7be7b6a 100644 --- a/src/Network/XMPP/Utilities.hs +++ b/src/Network/XMPP/Utilities.hs @@ -14,6 +14,7 @@ import Network.XMPP.Types import Control.Monad.STM import Control.Concurrent.STM.TVar import Prelude +import Control.Applicative (many) import qualified Data.Attoparsec.Text as AP import qualified Data.Text as Text @@ -83,7 +84,37 @@ versionFromNumbers major minor = Version major minor versionParser :: AP.Parser Version versionParser = do major <- AP.many1 AP.digit - AP.skip (\ c -> c == '.') + AP.skip (== '.') minor <- AP.many1 AP.digit AP.endOfInput - return $ Version (read major) (read minor) \ No newline at end of file + return $ Version (read major) (read minor) + + +-- | Parses, validates, and possibly constructs a "LangTag" object. +langTag :: Text.Text -> Maybe LangTag +langTag s = case AP.parseOnly langTagParser s of + Right tag -> Just tag + Left _ -> Nothing + + +-- Parses a language tag as defined by RFC 1766 and constructs a LangTag object. +langTagParser :: AP.Parser LangTag +langTagParser = do + -- Read until we reach a '-' character, or EOF. This is the `primary tag'. + primTag <- tag + -- Read zero or more subtags. + subTags <- many subtag + AP.endOfInput + return $ LangTag primTag subTags + where + tag :: AP.Parser Text.Text + tag = do + t <- AP.takeWhile1 $ AP.inClass tagChars + return t + subtag :: AP.Parser Text.Text + subtag = do + AP.skip (== '-') + subtag <- tag + return subtag + tagChars :: [Char] + tagChars = ['a'..'z'] ++ ['A'..'Z'] \ No newline at end of file