module Data.Generics.Serialization.Standard
(ext2Q, gSerial, gDeser, (=>>), (>>$), unfoldM, match, manySat, matchs,
getv_t, getcase, peekcase, matchws, space, readM, fromMaybeM, escape,
unescape, mkescape, breakr) where
import Data.Generics
import Data.Char
import Control.Monad
import Data.Generics.Serialization.Streams
infixl 1 >>$, =>>
ext2Q :: (Data d, Typeable2 t) =>
(d -> q) -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q)
-> (d -> q)
ext2Q def ext = unQ (Q def `ext2` Q ext)
newtype Q q x = Q { unQ :: x -> q }
ext2 :: (Data a, Typeable2 t)
=> c a
-> (forall a b. (Data a, Data b) => c (t a b))
-> c a
ext2 def ext = maybe def id (dataCast2 ext)
(=>>) :: Monad m => m a -> m b -> m a
(=>>) a b = do x <- a ; b ; return x
(>>$) :: Monad m => m a -> (a -> b) -> m b
(>>$) = flip liftM
unfoldM :: Monad m => m (Maybe a) -> m [a]
unfoldM a = a >>= maybe (return []) (\v -> liftM (v:) (unfoldM a))
gSerial :: (Data d, MonadWStream m c) =>
(forall a . Data a => a -> m ()) -> d -> (Constr, m ())
gSerial cld v = (toConstr v, gmapQl (>>) (return ()) cld v)
gDeser :: (Data d, Monad m) => (DataType -> m Constr) -> (forall a . Data a => m a) -> m d
gDeser rc cld = (\id -> do con <- rc (dataTypeOf (id undefined))
liftM id (fromConstrM cld con)) id
space :: MonadRStream m Char => m ()
space = do ch <- peekv
when (maybe False isSpace ch) $ getv >> space
match :: MonadRStream m Char => Char -> m ()
match ch = do chr <- getv ; when (chr /= ch) (fail ("expected '" ++ (ch:'\'':[])))
manySat :: MonadRStream m a => (a -> Bool) -> m [a]
manySat pred = do x <- peekv ; if (fmap pred x /= Just True)
then return []
else liftM2 (:) getv (manySat pred)
matchs :: MonadRStream m Char => [Char] -> m ()
matchs = mapM_ match
getv_t :: MonadRStream m a => m b -> m a
getv_t x = getv =>> x
getcase :: (Eq a, MonadRStream m a) => (a -> m b) -> [(a,m b)] -> m b
getcase def lst = getv >>= \x -> maybe (def x) id (lookup x lst)
peekcase :: (Eq a, MonadRStream m a) => m b -> (a -> m b) -> [(a,m b)] -> m b
peekcase eof def lst = do x <- peekv
case x of Nothing -> eof
Just x -> maybe (def x) id (lookup x lst)
matchws :: MonadRStream m Char => Char -> m ()
matchws ch = match ch >> space
readM :: (Monad m, Read a, Typeable a) => String -> m a
readM s = case filter ((=="").snd) $ reads s of
((n,_):_) -> return n
v -> fail ("expected " ++ show (typeOf (fst (head v))))
fromMaybeM :: Monad m => String -> Maybe a -> m a
fromMaybeM st = maybe (fail st) return
escape :: Char -> [Char] -> [Char] -> String -> String
escape ec badch repch = concatMap (\c -> case lookup c (zip badch repch) of
Nothing -> [c]
Just n -> [ec,n])
unescape :: Char -> [Char] -> [Char] -> String -> Maybe String
unescape ec usech repch = un' where
un' (x:y:xs) | x == ec = liftM2 (:) (lookup y (zip usech repch)) (un' xs)
un' (x:xs) = liftM (x :) (un' xs)
un' [] = Just []
mkescape :: Char -> [Char] -> [Char] -> (String->String, String->Maybe String)
mkescape ec badch repch = (escape ec badch repch, unescape ec repch badch)
breakr :: (a -> Bool) -> [a] -> ([a],[a])
breakr p lst = case break p $ reverse lst of
(a,(b:c)) -> (reverse c, b:reverse a)
(_,[]) -> (lst,[])