@@ -22,49 +22,53 @@ module Network.Google.Data.Time
23import Control.Lens
23import Control.Lens
24import Data.Aeson
24import Data.Aeson
25−import Data.Aeson.Encode
26−import qualified Data.Aeson.Types as Aeson
25+import qualified Data.Aeson.Types as Aeson
27import Data.Attoparsec.Text
26import Data.Attoparsec.Text
28−import Data.Bits ((.&.))
27+import Data.Bifunctor (first, second)
28+import Data.Bits ((.&.))
29−import Data.Char (ord)
29+import Data.Char (ord)
30−import Data.Data (Data, Typeable)
30+import Data.Data (Data, Typeable)
31−import Data.Text (Text)
31+import Data.Text (Text)
32−import qualified Data.Text as Text
32+import qualified Data.Text as Text
33−import qualified Data.Text.Lazy as LText
34−import qualified Data.Text.Lazy.Builder as Build
35import Data.Time
33import Data.Time
36import GHC.Generics
34import GHC.Generics
37−import Servant.Common.Text
35+import Web.HttpApiData (FromHttpApiData (..), ToHttpApiData (..))
39-- | This SHOULD be a time in the format of hh:mm:ss. It is
37-- | This SHOULD be a time in the format of hh:mm:ss. It is
40-- recommended that you use the "date-time" format instead of "time"
38-- recommended that you use the "date-time" format instead of "time"
41-- unless you need to transfer only the time part.
39-- unless you need to transfer only the time part.
42−newtype Time' = Time' TimeOfDay
40+newtype Time' = Time' { unTime :: TimeOfDay }
43 deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
41 deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
45_Time :: Iso' Time' TimeOfDay
43_Time :: Iso' Time' TimeOfDay
46−_Time = iso (\(Time' t) -> t) Time'
44+_Time = iso unTime Time'
46+instance ToHttpApiData Time' where
47+ toQueryParam = Text.pack . show . unTime
49+instance FromHttpApiData Time' where
50+ parseQueryParam = second Time' . parseText timeParser
48-- | This SHOULD be a date in the format of YYYY-MM-DD. It is
52-- | This SHOULD be a date in the format of YYYY-MM-DD. It is
49-- recommended that you use the "date-time" format instead of "date"
53-- recommended that you use the "date-time" format instead of "date"
50-- unless you need to transfer only the date part.
54-- unless you need to transfer only the date part.
51−newtype Date' = Date' Day
55+newtype Date' = Date' { unDate :: Day }
52− deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
56+ deriving (Eq, Ord, Show, Read, Generic, Data, Typeable, ToHttpApiData, FromHttpApiData)
54_Date :: Iso' Date' Day
58_Date :: Iso' Date' Day
55−_Date = iso (\(Date' t) -> t) Date'
59+_Date = iso unDate Date'
57-- | This SHOULD be a date in ISO 8601 format of YYYY-MM-
61-- | This SHOULD be a date in ISO 8601 format of YYYY-MM-
58-- DDThh:mm:ssZ in UTC time. This is the recommended form of date/timestamp.
62-- DDThh:mm:ssZ in UTC time. This is the recommended form of date/timestamp.
59−newtype DateTime' = DateTime' UTCTime
63+newtype DateTime' = DateTime' { unDateTime :: UTCTime }
60− deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
64+ deriving (Eq, Ord, Show, Read, Generic, Data, Typeable, ToHttpApiData, FromHttpApiData)
62_DateTime :: Iso' DateTime' UTCTime
66_DateTime :: Iso' DateTime' UTCTime
63−_DateTime = iso (\(DateTime' t) -> t) DateTime'
67+_DateTime = iso unDateTime DateTime'
65−instance FromText Time' where fromText = fmap Time' . parseText timeParser
69+instance ToJSON Time' where toJSON = String . toQueryParam
66−instance FromText Date' where fromText = fmap Date' . parseText dayParser
70+instance ToJSON Date' where toJSON = String . toQueryParam
67−instance FromText DateTime' where fromText = Aeson.parseMaybe parseJSON . String
71+instance ToJSON DateTime' where toJSON = toJSON . unDateTime
69instance FromJSON Time' where
73instance FromJSON Time' where
70 parseJSON = fmap Time' . withText "time" (run timeParser)
74 parseJSON = fmap Time' . withText "time" (run timeParser)
@@ -75,21 +79,8 @@ instance FromJSON Date' where
75instance FromJSON DateTime' where
79instance FromJSON DateTime' where
76 parseJSON = fmap DateTime' . parseJSON
80 parseJSON = fmap DateTime' . parseJSON
78−-- FIXME: Revisit once aeson-0.10 is more widely available.
79−instance ToText Time' where toText = Text.pack . show . view _Time
80−instance ToText Date' where toText = Text.pack . show . view _Date
81−instance ToText DateTime' where toText = encodeText
83−-- FIXME: Revisit once aeson-0.10 is more widely available.
84−instance ToJSON Time' where toJSON = String . toText
85−instance ToJSON Date' where toJSON = String . toText
86−instance ToJSON DateTime' where toJSON = toJSON . view _DateTime
88−parseText :: Parser a -> Text -> Maybe a
82+parseText :: Parser a -> Text -> Either Text a
89−parseText p = either (const Nothing) Just . parseOnly p
83+parseText p = first Text.pack . parseOnly p
91−encodeText :: ToJSON a => a -> Text
92−encodeText = LText.toStrict . Build.toLazyText . encodeToTextBuilder . toJSON
94-- | Parse a time of the form @HH:MM:SS@.
85-- | Parse a time of the form @HH:MM:SS@.
95timeParser :: Parser TimeOfDay
86timeParser :: Parser TimeOfDay