better recurrance formatting

This commit is contained in:
Joey Hess 2013-10-07 18:07:31 -04:00
parent b9375acb18
commit cf6403a13c

View file

@ -28,7 +28,6 @@ data Recurrance
| Weekly WeekDay | Weekly WeekDay
| Monthly MonthDay | Monthly MonthDay
| Yearly YearDay | Yearly YearDay
-- Divisible 3 Daily is every day of the year evenly divisible by 3
| Divisable Int Recurrance | Divisable Int Recurrance
deriving (Eq, Show, Ord) deriving (Eq, Show, Ord)
@ -38,15 +37,18 @@ type YearDay = Int
data TimeOfDay data TimeOfDay
= AnyTime = AnyTime
| Hour Int | SpecificTime Hour Minute
deriving (Eq, Show, Ord) deriving (Eq, Show, Ord)
type Hour = Int
type Minute = Int
data Duration = MinutesDuration Int data Duration = MinutesDuration Int
deriving (Eq, Show, Ord) deriving (Eq, Show, Ord)
fromRecurrance :: Recurrance -> String fromRecurrance :: Recurrance -> String
fromRecurrance (Divisable n r) = fromRecurrance (Divisable n r) =
fromRecurrance' (\u -> "on " ++ u ++ "s divisible by " ++ show n) r fromRecurrance' (++ "s divisible by " ++ show n) r
fromRecurrance r = fromRecurrance' ("every " ++) r fromRecurrance r = fromRecurrance' ("every " ++) r
fromRecurrance' :: (String -> String) -> Recurrance -> String fromRecurrance' :: (String -> String) -> Recurrance -> String
@ -57,38 +59,42 @@ fromRecurrance' a (Yearly n) = onday n (a "year")
fromRecurrance' a (Divisable _n r) = fromRecurrance' a r -- not used fromRecurrance' a (Divisable _n r) = fromRecurrance' a r -- not used
onday :: Int -> String -> String onday :: Int -> String -> String
onday n s = s ++ " on day " ++ show n onday n s = "on day " ++ show n ++ " of " ++ s
toRecurrance :: String -> Maybe Recurrance toRecurrance :: String -> Maybe Recurrance
toRecurrance s = case words s of toRecurrance s = case words s of
("every":something:l) -> parse something l ("every":"day":[]) -> Just Daily
("on":something:"divisible":"by":sn:l) -> do ("on":"day":sd:"of":"every":something:[]) -> parse something sd
r <- parse something l ("days":"divisible":"by":sn:[]) ->
n <- readish sn Divisable <$> getdivisor sn <*> pure Daily
if n > 0 ("on":"day":sd:"of":something:"divisible":"by":sn:[]) ->
then Just $ Divisable n r Divisable
else Nothing <$> getdivisor sn
<*> parse something sd
_ -> Nothing _ -> Nothing
where where
parse "day" [] = Just Daily parse "week" sd = withday Weekly sd
parse "week" l = withday Weekly l parse "month" sd = withday Monthly sd
parse "month" l = withday Monthly l parse "year" sd = withday Yearly sd
parse "year" l = withday Yearly l parse v sd
parse v l | "s" `isSuffixOf` v = parse (reverse $ drop 1 $ reverse v) sd
| "s" `isSuffixOf` v = parse (reverse $ drop 1 $ reverse v) l
| otherwise = Nothing | otherwise = Nothing
withday a ("on":"day":n:[]) = a <$> readish n withday c sd = c <$> readish sd
withday _ _ = Nothing getdivisor sn = do
n <- readish sn
if n > 0
then Just n
else Nothing
fromTimeOfDay :: TimeOfDay -> String fromTimeOfDay :: TimeOfDay -> String
fromTimeOfDay AnyTime = "any time" fromTimeOfDay AnyTime = "any time"
fromTimeOfDay (Hour n) = "hour " ++ show n fromTimeOfDay (SpecificTime h m) = show h ++ ":" ++ show m
toTimeOfDay :: String -> Maybe TimeOfDay toTimeOfDay :: String -> Maybe TimeOfDay
toTimeOfDay s = case words s of toTimeOfDay "any time" = Just AnyTime
("any":"time":[]) -> Just AnyTime toTimeOfDay s =
("hour":n:[]) -> Hour <$> readish n let (h, m) = separate (== ':') s
_ -> Nothing in SpecificTime <$> readish h <*> readish m
fromDuration :: Duration -> String fromDuration :: Duration -> String
fromDuration (MinutesDuration n) = show n ++ " minutes" fromDuration (MinutesDuration n) = show n ++ " minutes"
@ -137,7 +143,9 @@ instance Arbitrary Duration where
instance Arbitrary TimeOfDay where instance Arbitrary TimeOfDay where
arbitrary = oneof arbitrary = oneof
[ pure AnyTime [ pure AnyTime
, Hour <$> nonNegative arbitrary , SpecificTime
<$> nonNegative arbitrary
<*> nonNegative arbitrary
] ]
instance Arbitrary Recurrance where instance Arbitrary Recurrance where