module Language.Google.Search.Simple where
import Prelude
import Control.Monad.Free
import Data.Char (isSpace)
import Data.Foldable (fold)
import Data.List (intersperse)
import Data.Monoid
import Data.String (IsString (..))
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Lazy.Builder (Builder)
import qualified Data.Text.Lazy.Builder as B
data Duration = Days | Months | Years deriving (Show)
data Size = Bytes | KBytes | MBytes deriving (Show)
class SearchBuilder e where
searchBuilder :: e -> Builder
instance (Functor f, SearchBuilder a, SearchBuilder (f Builder)) =>
SearchBuilder (Free f a) where
searchBuilder = iter searchBuilder . fmap searchBuilder
data Term = Fuzzy Text | Exact Text deriving (Show)
instance IsString Term where fromString = Fuzzy . T.pack
instance SearchBuilder Term where
searchBuilder term = case term of
Fuzzy s -> ($ B.fromText s) $
if T.any isSpace s then ("(" <>) . (<> ")") else id
Exact s -> ($ B.fromText s) $
(B.singleton '"' <>) . (<> B.singleton '"')
data BooleanF e = Not e | And [e] | Or [e] deriving (Functor, Show)
instance SearchBuilder (BooleanF Builder) where
searchBuilder b = case b of
Not e -> "-" <> e
And es -> ("(" <>) . (<> ")") . fold $ intersperse " " es
Or es -> ("(" <>) . (<> ")") . fold $ intersperse " OR " es
type BooleanM = Free BooleanF
instance (IsString a) => IsString (BooleanM a) where
fromString = return . fromString
type Simple = BooleanM Term
fAnd :: [BooleanM a] -> BooleanM a
fAnd = Free . And
fOr :: [BooleanM a] -> BooleanM a
fOr = Free . Or
fNot :: BooleanM a -> BooleanM a
fNot = Free . Not