{-# LANGUAGE CPP #-} module Sound.Freesound.Search.Numerical ( Numerical , equals , between , lessThan , greaterThan ) where import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS import qualified Data.Time.Clock as Time import qualified Data.Time.Format as Time import Network.HTTP.Types.QueryLike (QueryValueLike(..)) import Sound.Freesound.Sound.Type (SoundId, soundIdToInteger) #if __GLASGOW_HASKELL__ < 710 import System.Locale (defaultTimeLocale) #else import Data.Time (defaultTimeLocale) #endif -- | Numerical constraint. data Numerical a = Equals a | Between a a | GreaterThan a | LessThan a deriving (Eq, Show) class NumericalQueryValue a where toNumericalQueryValue :: a -> ByteString instance NumericalQueryValue Double where toNumericalQueryValue = BS.pack . show instance NumericalQueryValue Integer where toNumericalQueryValue = BS.pack . show instance NumericalQueryValue SoundId where toNumericalQueryValue = BS.pack . show . soundIdToInteger instance NumericalQueryValue Time.UTCTime where toNumericalQueryValue = BS.pack . Time.formatTime defaultTimeLocale "%FT%H:%M:%S%QZ" equals :: a -> Numerical a equals = Equals between :: Ord a => a -> a -> Numerical a between a b | a <= b = Between a b | otherwise = Between b a greaterThan :: a -> Numerical a greaterThan = GreaterThan lessThan :: a -> Numerical a lessThan = LessThan wrap :: ByteString -> ByteString -> ByteString wrap a b = BS.unwords [ BS.pack "[", a, BS.pack "TO", b, BS.pack "]" ] wildcard :: ByteString wildcard = BS.pack "*" instance (NumericalQueryValue a) => QueryValueLike (Numerical a) where toQueryValue (Equals a) = toQueryValue $ toNumericalQueryValue a toQueryValue (Between a b) = toQueryValue $ wrap (toNumericalQueryValue a) (toNumericalQueryValue b) toQueryValue (GreaterThan a) = toQueryValue $ wrap (toNumericalQueryValue a) wildcard toQueryValue (LessThan a) = toQueryValue $ wrap wildcard (toNumericalQueryValue a)