module OpcXmlDaClient.XmlSchemaValues.Attoparsec
  ( dateTime,
    time,
    date,
    duration,
  )
where

import qualified Attoparsec.Data as Ad
import Data.Attoparsec.Text
import qualified Data.Text as Text
import qualified Data.Time.Format.ISO8601 as Iso8601
import OpcXmlDaClient.Base.Prelude
import OpcXmlDaClient.XmlSchemaValues.Types
import qualified OpcXmlDaClient.XmlSchemaValues.Util.TimeMath as TimeMath

-- |
-- XML Schema dateTime.
--
-- https://www.w3.org/TR/xmlschema-2/#dateTime
dateTime :: Parser UTCTime
dateTime :: Parser UTCTime
dateTime = Parser UTCTime
Ad.utcTimeInISO8601

-- |
-- XML Schema time.
--
-- https://www.w3.org/TR/xmlschema-2/#time
time :: Parser Time
time :: Parser Time
time = do
  TimeOfDay
_timeOfDay <- Parser TimeOfDay
Ad.timeOfDayInISO8601
  Maybe TimeZone
_timeZone <- Parser Text TimeZone -> Parser Text (Maybe TimeZone)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Text TimeZone
Ad.timeZoneInISO8601
  return $ TimeOfDay -> Maybe TimeZone -> Time
Time TimeOfDay
_timeOfDay Maybe TimeZone
_timeZone

-- |
-- XML Schema date.
--
-- https://www.w3.org/TR/xmlschema-2/#date
date :: Parser Date
date :: Parser Date
date = do
  Parser Text Day -> Parser Text Day
_applyNeg <- (Day -> Day) -> Parser Text Day -> Parser Text Day
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Day -> Day
TimeMath.negateDay (Parser Text Day -> Parser Text Day)
-> Parser Text Char
-> Parser Text (Parser Text Day -> Parser Text Day)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> Parser Text Char
char Char
'-' Parser Text (Parser Text Day -> Parser Text Day)
-> Parser Text (Parser Text Day -> Parser Text Day)
-> Parser Text (Parser Text Day -> Parser Text Day)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text Day -> Parser Text Day)
-> Parser Text (Parser Text Day -> Parser Text Day)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Parser Text Day -> Parser Text Day
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  Day
_day <- Parser Text Day -> Parser Text Day
_applyNeg Parser Text Day
Ad.dayInISO8601
  Maybe TimeZone
_timeZone <- Parser Text TimeZone -> Parser Text (Maybe TimeZone)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Text TimeZone
Ad.timeZoneInISO8601
  return $ Day -> Maybe TimeZone -> Date
Date Day
_day Maybe TimeZone
_timeZone

-- |
-- XML Schema duration.
--
-- https://www.w3.org/TR/xmlschema-2/#duration
duration :: Parser Duration
duration :: Parser Duration
duration = do
  Bool
_pos <- Bool
False Bool -> Parser Text Char -> Parser Text Bool
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> Parser Text Char
char Char
'-' Parser Text Bool -> Parser Text Bool -> Parser Text Bool
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Bool -> Parser Text Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
  Text
_textRemainder <- Parser Text
takeText
  CalendarDiffTime
_diff <- String -> Parser Text CalendarDiffTime
forall (m :: * -> *) t. (MonadFail m, ISO8601 t) => String -> m t
Iso8601.iso8601ParseM (String -> Parser Text CalendarDiffTime)
-> String -> Parser Text CalendarDiffTime
forall a b. (a -> b) -> a -> b
$ Text -> String
Text.unpack Text
_textRemainder
  return $ Bool -> CalendarDiffTime -> Duration
Duration Bool
_pos CalendarDiffTime
_diff