aboutsummaryrefslogtreecommitdiff
path: root/src/Birthdate.hs
blob: 2ef1bcb14ad127d83e3b547740d6dd34a10d55a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
{-# LANGUAGE OverloadedStrings #-}

module Birthdate
  ( Birthdate(..)
  , fullname
  , age
  , readBirthdates
  , filterBirthday
  ) where

import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Read as T
import Data.Either (partitionEithers)

import Date (Date(Date), sameDayAndMonth, yearsGap)

data Birthdate = Birthdate
  { date :: Date
  , lastname :: Text
  , firstname :: Text
  } deriving (Eq, Show)

fullname :: Birthdate -> Text
fullname d = T.concat [firstname d, " ", lastname d]

age :: Date -> Birthdate -> Int
age currentDate birthdate = yearsGap currentDate (date birthdate)

readBirthdates :: FilePath -> IO (Either Text [Birthdate])
readBirthdates path = do
  eitherBirthdates <- map parseBirthdate . zip [1..] . T.lines <$> T.readFile path
  return $
    case partitionEithers eitherBirthdates of
      ([], birthdates) ->
        Right birthdates
      (errors, _) ->
        Left $ T.intercalate "\n" errors

parseBirthdate :: (Int, Text) -> Either Text Birthdate
parseBirthdate (line, text) =
  case map T.strip $ T.splitOn "," text of
    [date, lastname, firstname] ->
      case map T.decimal $ T.splitOn "/" date of
        [Right (day, ""), Right (month, ""), Right (year, "")] ->
          Right Birthdate
            { date = Date year month day
            , lastname = lastname
            , firstname = firstname
            }
        _ ->
          Left $ T.concat
            [ lineOutput line
            , " birthdate: "
            , date
            , ". (Required: year/month/day)"
            ]
    _ ->
      Left $ T.concat
        [ lineOutput line
        , " line: "
        , text
        , ". (Required: date, lastname, firstname)"
        ]

lineOutput :: Int -> Text
lineOutput line =
  T.concat
    [ "[L"
    , T.pack . show $ line
    , "]"
    ]

filterBirthday :: Date -> [Birthdate] -> [Birthdate]
filterBirthday d = filter (sameDayAndMonth d . date)