{-# LANGUAGE FlexibleContexts #-}

module Saturn.Unstable.Type.Hour where

import qualified Data.Coerce as Coerce
import qualified Data.Set as Set
import qualified Data.Text.Lazy.Builder as Builder
import qualified Data.Word as Word
import qualified Saturn.Unstable.Type.Field as Field
import qualified Text.Parsec as Parsec

newtype Hour
  = Hour Field.Field
  deriving (Hour -> Hour -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Hour -> Hour -> Bool
$c/= :: Hour -> Hour -> Bool
== :: Hour -> Hour -> Bool
$c== :: Hour -> Hour -> Bool
Eq, Int -> Hour -> ShowS
[Hour] -> ShowS
Hour -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Hour] -> ShowS
$cshowList :: [Hour] -> ShowS
show :: Hour -> String
$cshow :: Hour -> String
showsPrec :: Int -> Hour -> ShowS
$cshowsPrec :: Int -> Hour -> ShowS
Show)

bounds :: (Word.Word8, Word.Word8)
bounds :: (Word8, Word8)
bounds = (Word8
0, Word8
23)

fromField :: Field.Field -> Maybe Hour
fromField :: Field -> Maybe Hour
fromField Field
field =
  if (Word8, Word8) -> Field -> Bool
Field.isValid (Word8, Word8)
bounds Field
field then forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Field -> Hour
Hour Field
field else forall a. Maybe a
Nothing

toField :: Hour -> Field.Field
toField :: Hour -> Field
toField = coerce :: forall a b. Coercible a b => a -> b
Coerce.coerce

parsec :: (Parsec.Stream s m Char) => Parsec.ParsecT s u m Hour
parsec :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Hour
parsec = do
  Field
field <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Field
Field.parsec
  forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"invalid Hour") forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Field -> Maybe Hour
fromField Field
field

toBuilder :: Hour -> Builder.Builder
toBuilder :: Hour -> Builder
toBuilder = Field -> Builder
Field.toBuilder forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hour -> Field
toField

expand :: Hour -> Set.Set Word.Word8
expand :: Hour -> Set Word8
expand = (Word8, Word8) -> Field -> Set Word8
Field.expand (Word8, Word8)
bounds forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hour -> Field
toField

isMatch :: Word.Word8 -> Hour -> Bool
isMatch :: Word8 -> Hour -> Bool
isMatch Word8
word8 = forall a. Ord a => a -> Set a -> Bool
Set.member Word8
word8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hour -> Set Word8
expand