on develop help sign in
Reordering cabal dependencies and adding lower bounds
commit07df0a21166a1de9411bdfb129cc11e693fe7efd authorBrendan Hay <brendan.g.hay@gmail.com> dateThu 15 Oct 2015, 18:56 (11 years ago) parentf478dee
3 files changed+143−51
core/gogol-core.cabal+18−17 core/src/Network/Google/Data/Time.hs+105−13 gogol/gogol.cabal+20−21
core/gogol-core.cabal+18−17
@@ -43,23 +43,24 @@ library
4343 , Network.Google.Types
4444
4545 build-depends:
46− aeson >= 0.8
47− , base >= 4.7 && < 5
48− , bytestring >= 0.9
49− , conduit >= 1.1
50− , dlist >= 0.7
51− , case-insensitive >= 1.2
52− , exceptions >= 0.6
53− , hashable >= 1.2
54− , http-client >= 0.4.4
55− , http-media >= 0.6
56− , http-types >= 0.8.6
57− , lens >= 4.4
58− , resourcet >= 1.1
59− , scientific >= 0.3
60− , servant >= 0.4.4
61− , text >= 1.1
62− , unordered-containers
46+ aeson >= 0.8
47+ , attoparsec >= 0.11.3
48+ , base >= 4.7 && < 5
49+ , bytestring >= 0.9
50+ , case-insensitive >= 1.2
51+ , conduit >= 1.1
52+ , dlist >= 0.7
53+ , exceptions >= 0.6
54+ , hashable >= 1.2
55+ , http-client >= 0.4.4
56+ , http-media >= 0.6
57+ , http-types >= 0.8.6
58+ , lens >= 4.4
59+ , resourcet >= 1.1
60+ , scientific >= 0.3
61+ , servant >= 0.4.4
62+ , text >= 1.1
63+ , unordered-containers >= 0.2.5
6364
6465 if !impl(ghc>=7.9)
6566 build-depends:
core/src/Network/Google/Data/Time.hs+105−13
@@ -10,24 +10,116 @@
1010-- Stability : provisional
1111-- Portability : non-portable (GHC extensions)
1212--
13−module Network.Google.Data.Time where
13+module Network.Google.Data.Time
14+ ( Time' (..)
15+ , Date' (..)
16+ , DateTime' (..)
1417
18+ , _Time
19+ , _Date
20+ , _DateTime
21+ ) where
22+
23+import Control.Lens
1524import Data.Aeson
16−import Data.Data (Data, Typeable)
17−import Data.Text (Text)
25+import Data.Aeson.Encode
26+import qualified Data.Aeson.Types as Aeson
27+import Data.Attoparsec.Text
28+import Data.Bits ((.&.))
29+import Data.Char (ord)
30+import Data.Data (Data, Typeable)
31+import Data.Text (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
1835import Data.Time
1936import GHC.Generics
20−import Servant.API (FromText, ToText)
37+import Servant.Common.Text
38+
39+-- | 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"
41+-- unless you need to transfer only the time part.
42+newtype Time' = Time' TimeOfDay
43+ deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
44+
45+_Time :: Iso' Time' TimeOfDay
46+_Time = iso (\(Time' t) -> t) Time'
47+
48+-- | 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"
50+-- unless you need to transfer only the date part.
51+newtype Date' = Date' Day
52+ deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
53+
54+_Date :: Iso' Date' Day
55+_Date = iso (\(Date' t) -> t) Date'
56+
57+-- | 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.
59+newtype DateTime' = DateTime' UTCTime
60+ deriving (Eq, Ord, Show, Read, Generic, Data, Typeable)
61+
62+_DateTime :: Iso' DateTime' UTCTime
63+_DateTime = iso (\(DateTime' t) -> t) DateTime'
64+
65+instance FromText Time' where fromText = fmap Time' . parseText timeParser
66+instance FromText Date' where fromText = fmap Date' . parseText dayParser
67+instance FromText DateTime' where fromText = Aeson.parseMaybe parseJSON . String
68+
69+instance FromJSON Time' where
70+ parseJSON = fmap Time' . withText "time" (run timeParser)
71+
72+instance FromJSON Date' where
73+ parseJSON = fmap Date' . withText "date" (run dayParser)
74+
75+instance FromJSON DateTime' where
76+ parseJSON = fmap DateTime' . parseJSON
77+
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
82+
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
87+
88+parseText :: Parser a -> Text -> Maybe a
89+parseText p = either (const Nothing) Just . parseOnly p
90+
91+encodeText :: ToJSON a => a -> Text
92+encodeText = LText.toStrict . Build.toLazyText . encodeToTextBuilder . toJSON
2193
22−_Time = undefined
23−_Date = undefined
24−_DateTime = undefined
94+-- | Parse a time of the form @HH:MM:SS@.
95+timeParser :: Parser TimeOfDay
96+timeParser = do
97+ h <- twoDigits <* char ':'
98+ m <- twoDigits <* char ':'
99+ s <- twoDigits <&> fromIntegral
100+ if h < 24 && m < 60 && s < 61
101+ then pure (TimeOfDay h m s)
102+ else fail "invalid time"
25103
26−newtype Time' = Time' Text -- TimeOfDay
27− deriving (Eq, Ord, Show, Read, Generic, Data, Typeable, FromText, ToText, FromJSON, ToJSON)
104+-- | Parse a date of the form @YYYY-MM-DD@.
105+dayParser :: Parser Day
106+dayParser = do
107+ y <- decimal <* char '-'
108+ m <- twoDigits <* char '-'
109+ d <- twoDigits
110+ maybe (fail "invalid date") pure (fromGregorianValid y m d)
28111
29−newtype Date' = Date' Text -- LocalTime
30− deriving (Eq, Ord, Show, Read, Generic, Data, Typeable, FromText, ToText, FromJSON, ToJSON)
112+-- | Parse a two-digit integer (e.g. day of month, hour).
113+twoDigits :: Parser Int
114+twoDigits = do
115+ a <- digit
116+ b <- digit
117+ let c2d c = ord c .&. 15
118+ pure $! c2d a * 10 + c2d b
31119
32−newtype DateTime' = DateTime' Text -- UTCTime
33− deriving (Eq, Ord, Show, Read, Generic, Data, Typeable, FromText, ToText, FromJSON, ToJSON)
120+-- | Run an attoparsec parser as an aeson parser.
121+run :: Parser a -> Text -> Aeson.Parser a
122+run p t =
123+ case parseOnly (p <* endOfInput) t of
124+ Left err -> fail $ "could not parse date: " ++ err
125+ Right r -> pure r
gogol/gogol.cabal+20−21
@@ -35,24 +35,23 @@ library
3535 Network.Google.Internal.HTTP
3636
3737 build-depends:
38− base >= 4.7 && < 5
39− , data-default-class >= 0.0.1
40− , exceptions >= 0.6
41− , gogol-core == 0.0.1.*
42− , http-conduit >= 2.1.4
43− , http-media >= 0.6
44− , http-types >= 0.8.6
45− , lens >= 4.4
46− , monad-control >= 1
47− , mtl >= 2.1.3.1
48− , resourcet >= 1.1
49− , text >= 1.1
50− , transformers >= 0.2
51− , transformers-base >= 0.4
52− , bytestring
53− , time
54− , aeson
55− , exceptions
56− , unordered-containers
57− , filepath
58− , directory
38+ aeson >= 0.8
39+ , base >= 4.7 && < 5
40+ , bytestring >= 0.9
41+ , data-default-class >= 0.0.1
42+ , directory >= 1.2
43+ , exceptions >= 0.6
44+ , filepath >= 1.2
45+ , gogol-core == 0.0.1.*
46+ , http-conduit >= 2.1.4
47+ , http-media >= 0.6
48+ , http-types >= 0.8.6
49+ , lens >= 4.4
50+ , monad-control >= 1
51+ , mtl >= 2.1.3.1
52+ , resourcet >= 1.1
53+ , text >= 1.1
54+ , time >= 1.2
55+ , transformers >= 0.2
56+ , transformers-base >= 0.4
57+ , unordered-containers >= 0.2.5