-- | This internal module is mostly here to prevent CPP conflicting with Haskell
-- comments.
module Hakyll.Core.Identifier.Pattern.Internal
    ( GlobComponent (..)
    , Pattern (..)
    ) where


--------------------------------------------------------------------------------
import           Data.Binary            (Binary (..), getWord8, putWord8)
import           Data.Set               (Set)


--------------------------------------------------------------------------------
import           Hakyll.Core.Identifier


--------------------------------------------------------------------------------
-- | Elements of a glob pattern
data GlobComponent
    = Capture
    | CaptureMany
    | Literal String
    deriving (GlobComponent -> GlobComponent -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GlobComponent -> GlobComponent -> Bool
$c/= :: GlobComponent -> GlobComponent -> Bool
== :: GlobComponent -> GlobComponent -> Bool
$c== :: GlobComponent -> GlobComponent -> Bool
Eq, Int -> GlobComponent -> ShowS
[GlobComponent] -> ShowS
GlobComponent -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GlobComponent] -> ShowS
$cshowList :: [GlobComponent] -> ShowS
show :: GlobComponent -> String
$cshow :: GlobComponent -> String
showsPrec :: Int -> GlobComponent -> ShowS
$cshowsPrec :: Int -> GlobComponent -> ShowS
Show)


--------------------------------------------------------------------------------
instance Binary GlobComponent where
    put :: GlobComponent -> Put
put GlobComponent
Capture     = Word8 -> Put
putWord8 Word8
0
    put GlobComponent
CaptureMany = Word8 -> Put
putWord8 Word8
1
    put (Literal String
s) = Word8 -> Put
putWord8 Word8
2 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put String
s

    get :: Get GlobComponent
get = Get Word8
getWord8 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
t -> case Word8
t of
        Word8
0 -> forall (f :: * -> *) a. Applicative f => a -> f a
pure GlobComponent
Capture
        Word8
1 -> forall (f :: * -> *) a. Applicative f => a -> f a
pure GlobComponent
CaptureMany
        Word8
2 -> String -> GlobComponent
Literal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get
        Word8
_ -> forall a. HasCallStack => String -> a
error String
"Data.Binary.get: Invalid GlobComponent"


--------------------------------------------------------------------------------
-- | Type that allows matching on identifiers
data Pattern
    = Everything
    | Complement Pattern
    | And Pattern Pattern
    | Glob [GlobComponent]
    | List (Set Identifier)
    | Regex String
    | Version (Maybe String)
    deriving (Int -> Pattern -> ShowS
[Pattern] -> ShowS
Pattern -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pattern] -> ShowS
$cshowList :: [Pattern] -> ShowS
show :: Pattern -> String
$cshow :: Pattern -> String
showsPrec :: Int -> Pattern -> ShowS
$cshowsPrec :: Int -> Pattern -> ShowS
Show)


--------------------------------------------------------------------------------
instance Binary Pattern where
    put :: Pattern -> Put
put Pattern
Everything     = Word8 -> Put
putWord8 Word8
0
    put (Complement Pattern
p) = Word8 -> Put
putWord8 Word8
1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put Pattern
p
    put (And Pattern
x Pattern
y)      = Word8 -> Put
putWord8 Word8
2 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put Pattern
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put Pattern
y
    put (Glob [GlobComponent]
g)       = Word8 -> Put
putWord8 Word8
3 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put [GlobComponent]
g
    put (List Set Identifier
is)      = Word8 -> Put
putWord8 Word8
4 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put Set Identifier
is
    put (Regex String
r)      = Word8 -> Put
putWord8 Word8
5 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put String
r
    put (Version Maybe String
v)    = Word8 -> Put
putWord8 Word8
6 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put Maybe String
v

    get :: Get Pattern
get = Get Word8
getWord8 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
t -> case Word8
t of
        Word8
0 -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pattern
Everything
        Word8
1 -> Pattern -> Pattern
Complement forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get
        Word8
2 -> Pattern -> Pattern -> Pattern
And forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall t. Binary t => Get t
get
        Word8
3 -> [GlobComponent] -> Pattern
Glob forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get
        Word8
4 -> Set Identifier -> Pattern
List forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get
        Word8
5 -> String -> Pattern
Regex forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get
        Word8
_ -> Maybe String -> Pattern
Version forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t. Binary t => Get t
get


--------------------------------------------------------------------------------
instance Semigroup Pattern where
    <> :: Pattern -> Pattern -> Pattern
(<>) = Pattern -> Pattern -> Pattern
And

instance Monoid Pattern where
    mempty :: Pattern
mempty  = Pattern
Everything
    mappend :: Pattern -> Pattern -> Pattern
mappend = forall a. Semigroup a => a -> a -> a
(<>)