@@ -1,3 +1,5 @@
1+{-# LANGUAGE AllowAmbiguousTypes #-}
2+{-# LANGUAGE CPP #-}
13module Data.Time.Fmt
24 ( FmtTime(..)
35 , _FmtTime
@@ -26,6 +28,10 @@ import Text.XML.DOM.Parser
2628import Text.XML.Writer
2729import Web.HttpApiData
2830
31+#if !MIN_VERSION_base(4,13,0)
32+import Control.Monad.Fail
33+#endif
34+
2935
3036newtype FmtTime (fmt :: Symbol) a = FmtTime
3137 { unFmtTime :: a
@@ -43,7 +49,7 @@ fmtTimeToString =
4349
4450fmtTimeFromString
4551 :: forall a fmt m
46− . (ParseTime a, KnownSymbol fmt, Monad m)
52+ . (ParseTime a, KnownSymbol fmt, MonadFail m)
4753 => String
4854 -> m (FmtTime fmt a)
4955fmtTimeFromString =
@@ -67,11 +73,14 @@ instance (ParseTime a, KnownSymbol fmt) => FromJSON (FmtTime fmt a) where
6773instance (FormatTime a, KnownSymbol fmt) => ToHttpApiData (FmtTime fmt a) where
6874 toUrlPiece = T.pack . fmtTimeToString
6975
76+errParseFmtTime
77+ :: forall fmt s. (KnownSymbol fmt, IsString s, Semigroup s) => s -> s
78+errParseFmtTime t =
79+ "no parse " <> t <> " as " <> fromString (symbolVal (Proxy @fmt))
80+
7081instance (ParseTime a, KnownSymbol fmt) => FromHttpApiData (FmtTime fmt a) where
71− parseUrlPiece t = maybe err Right $ fmtTimeFromString $ T.unpack t
72− where
73− fmt = T.pack $ symbolVal (Proxy @fmt)
74− err = Left $ "no parse " <> t <> " as " <> fmt
82+ parseUrlPiece t =
83+ maybe (Left $ errParseFmtTime @fmt t) Right $ fmtTimeFromString $ T.unpack t
7584
7685instance (FormatTime a, KnownSymbol fmt) => ToXML (FmtTime fmt a) where
7786 toXML = toXML . T.pack . fmtTimeToString
@@ -79,10 +88,8 @@ instance (FormatTime a, KnownSymbol fmt) => ToXML (FmtTime fmt a) where
7988instance (ParseTime a, KnownSymbol fmt) => FromDom (FmtTime fmt a) where
8089 fromDom = do
8190 s <- fromDom
82− case fmtTimeFromString s of
83− Right a -> return a
84− Left e -> throwParserError $
85− PEContentWrongFormat (T.pack e)
91+ maybe (throwParserError $ PEContentWrongFormat $ errParseFmtTime @fmt s)
92+ pure $ fmtTimeFromString $ T.unpack s
8693
8794type ZonedISO8601 = ("%FT%T%Q%z" :: Symbol)
8895