1 module Snap.Util.Readable 2 ( Readable(..) 3 ) where 4 5 ------------------------------------------------------------------------------ 6 import Data.ByteString.Char8 (ByteString) 7 import Data.Text (Text) 8 import qualified Data.Text as T 9 import Data.Text.Encoding 10 import Data.Text.Read 11 12 13 ------------------------------------------------------------------------------ 14 -- | Runs a 'Snap' monad action only when 'rqPathInfo' is empty. 15 class Readable a where 16 fromBS :: Monad m => ByteString -> m a 17 18 19 ------------------------------------------------------------------------------ 20 -- | Fails if the input wasn't parsed completely. 21 checkComplete :: Monad m => (t, Text) -> m t 22 checkComplete (a,rest) 23 | T.null rest = return a 24 | otherwise = fail "Readable: could not parse completely" 25 26 27 instance Readable ByteString where 28 fromBS = return 29 instance Readable Text where 30 fromBS = return . decodeUtf8 31 instance Readable Int where 32 fromBS = either fail checkComplete . decimal . decodeUtf8 33 instance Readable Integer where 34 fromBS = either fail checkComplete . decimal . decodeUtf8 35 instance Readable Double where 36 fromBS = either fail checkComplete . double . decodeUtf8