module Network.MPD.Commands.Query (Query, (=?) ,(/=?), (%?), (~?), (/~?), qNot, qModSince, qFile, qBase, anything) where
import Network.MPD.Commands.Arg
import Network.MPD.Commands.Types
import Data.Time (UTCTime,formatTime,defaultTimeLocale)
data Query = Query [Match] | Filter Expr
deriving Int -> Query -> ShowS
[Query] -> ShowS
Query -> String
(Int -> Query -> ShowS)
-> (Query -> String) -> ([Query] -> ShowS) -> Show Query
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Query -> ShowS
showsPrec :: Int -> Query -> ShowS
$cshow :: Query -> String
show :: Query -> String
$cshowList :: [Query] -> ShowS
showList :: [Query] -> ShowS
Show
data Match = Match Metadata Value
instance Show Match where
show :: Match -> String
show (Match Metadata
meta Value
query) = Metadata -> String
forall a. Show a => a -> String
show Metadata
meta String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" \"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. ToString a => a -> String
toString Value
query String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\""
showList :: [Match] -> ShowS
showList [Match]
xs String
_ = [String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (Match -> String) -> [Match] -> [String]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Match -> String
forall a. Show a => a -> String
show [Match]
xs
data Expr = Exact Match
| ExactNot Match
| Contains Match
| Regex Match
| RegexNot Match
| File Path
| Base Path
| ModifiedSince UTCTime
| ExprNot Expr
| ExprAnd Expr Expr
| ExprEmpty
instance Show Expr where
show :: Expr -> String
show (Exact (Match Metadata
meta Value
query)) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Metadata -> String
forall a. Show a => a -> String
show Metadata
meta String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" == " String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. ToString a => a -> String
toString Value
query String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (ExactNot (Match Metadata
meta Value
query)) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Metadata -> String
forall a. Show a => a -> String
show Metadata
meta String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" != " String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. ToString a => a -> String
toString Value
query String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Contains (Match Metadata
meta Value
query)) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Metadata -> String
forall a. Show a => a -> String
show Metadata
meta String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" contains " String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. ToString a => a -> String
toString Value
query String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Regex (Match Metadata
meta Value
query)) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Metadata -> String
forall a. Show a => a -> String
show Metadata
meta String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" =~ " String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. ToString a => a -> String
toString Value
query String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (RegexNot (Match Metadata
meta Value
query)) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Metadata -> String
forall a. Show a => a -> String
show Metadata
meta String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" !~ " String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. ToString a => a -> String
toString Value
query String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (File Path
file) = String
"(file == " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Path -> String
forall a. ToString a => a -> String
toString Path
file String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Base Path
dir) = String
"(base " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Path -> String
forall a. ToString a => a -> String
toString Path
dir String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (ModifiedSince UTCTime
time) = String
"(modified-since " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++
TimeLocale -> String -> UTCTime -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%Y-%m-%dT%H:%M:%SZ" UTCTime
time String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"\\\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (ExprNot Expr
expr) = String
"(!" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr -> String
forall a. Show a => a -> String
show Expr
expr String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (ExprAnd Expr
e1 Expr
e2) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr -> String
forall a. Show a => a -> String
show Expr
e1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" AND " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr -> String
forall a. Show a => a -> String
show Expr
e2 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show Expr
ExprEmpty = String
""
toExpr :: [Match] -> Expr
toExpr :: [Match] -> Expr
toExpr [] = Expr
ExprEmpty
toExpr (Match
m:[]) = Match -> Expr
Exact Match
m
toExpr (Match
m:[Match]
ms) = Expr -> Expr -> Expr
ExprAnd (Match -> Expr
Exact Match
m) ([Match] -> Expr
toExpr [Match]
ms)
instance Monoid Query where
mempty :: Query
mempty = [Match] -> Query
Query []
Query [Match]
a mappend :: Query -> Query -> Query
`mappend` Query [Match]
b = [Match] -> Query
Query ([Match]
a [Match] -> [Match] -> [Match]
forall a. [a] -> [a] -> [a]
++ [Match]
b)
Query [] `mappend` Filter Expr
b = Expr -> Query
Filter Expr
b
Filter Expr
a `mappend` Query [] = Expr -> Query
Filter Expr
a
Query [Match]
a `mappend` Filter Expr
b = Expr -> Query
Filter (Expr -> Expr -> Expr
ExprAnd ([Match] -> Expr
toExpr [Match]
a) Expr
b)
Filter Expr
a `mappend` Query [Match]
b = Expr -> Query
Filter (Expr -> Expr -> Expr
ExprAnd Expr
a ([Match] -> Expr
toExpr [Match]
b))
Filter Expr
a `mappend` Filter Expr
b = Expr -> Query
Filter (Expr
a Expr -> Expr -> Expr
forall a. Semigroup a => a -> a -> a
<> Expr
b)
instance Semigroup Query where
<> :: Query -> Query -> Query
(<>) = Query -> Query -> Query
forall a. Monoid a => a -> a -> a
mappend
instance Semigroup Expr where
Expr
ex1 <> :: Expr -> Expr -> Expr
<> Expr
ex2 = Expr -> Expr -> Expr
ExprAnd Expr
ex1 Expr
ex2
instance MPDArg Query where
prep :: Query -> Args
prep (Query [Match]
ms) = (Args -> Args -> Args) -> Args -> [Args] -> Args
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Args -> Args -> Args
forall a b. (MPDArg a, MPDArg b) => a -> b -> Args
(<++>) ([String] -> Args
Args [])
((Match -> Args) -> [Match] -> [Args]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Match Metadata
m Value
q) -> [String] -> Args
Args [Metadata -> String
forall a. Show a => a -> String
show Metadata
m] Args -> Value -> Args
forall a b. (MPDArg a, MPDArg b) => a -> b -> Args
<++> Value
q) [Match]
ms)
prep (Filter Expr
expr) = [String] -> Args
Args [String
"\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr -> String
forall a. Show a => a -> String
show Expr
expr String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\""]
anything :: Query
anything :: Query
anything = Query
forall a. Monoid a => a
mempty
(=?) :: Metadata -> Value -> Query
Metadata
m =? :: Metadata -> Value -> Query
=? Value
s = [Match] -> Query
Query [Metadata -> Value -> Match
Match Metadata
m Value
s]
(/=?) :: Metadata -> Value -> Query
Metadata
m /=? :: Metadata -> Value -> Query
/=? Value
s = Expr -> Query
Filter (Match -> Expr
ExactNot (Metadata -> Value -> Match
Match Metadata
m Value
s))
(%?) :: Metadata -> Value -> Query
Metadata
m %? :: Metadata -> Value -> Query
%? Value
s = Expr -> Query
Filter (Match -> Expr
Contains (Metadata -> Value -> Match
Match Metadata
m Value
s))
(~?) :: Metadata -> Value -> Query
Metadata
m ~? :: Metadata -> Value -> Query
~? Value
s = Expr -> Query
Filter (Match -> Expr
Regex (Metadata -> Value -> Match
Match Metadata
m Value
s))
(/~?) :: Metadata -> Value -> Query
Metadata
m /~? :: Metadata -> Value -> Query
/~? Value
s = Expr -> Query
Filter (Match -> Expr
RegexNot (Metadata -> Value -> Match
Match Metadata
m Value
s))
qNot :: Query -> Query
qNot :: Query -> Query
qNot (Query [Match]
ms) = Expr -> Query
Filter (Expr -> Expr
ExprNot ([Match] -> Expr
toExpr [Match]
ms))
qNot (Filter (ExprNot Expr
ex)) = Expr -> Query
Filter Expr
ex
qNot (Filter Expr
ex) = Expr -> Query
Filter (Expr -> Expr
ExprNot Expr
ex)
qModSince :: UTCTime -> Query
qModSince :: UTCTime -> Query
qModSince UTCTime
time = Expr -> Query
Filter (UTCTime -> Expr
ModifiedSince UTCTime
time)
qFile :: Path -> Query
qFile :: Path -> Query
qFile Path
file = Expr -> Query
Filter (Path -> Expr
File Path
file)
qBase :: Path -> Query
qBase :: Path -> Query
qBase Path
dir = Expr -> Query
Filter (Path -> Expr
Base Path
dir)