
Hi Adam,
somehow I can't get it to work according to yours and Chris' examples. I
have the following test-case:
-----
stamp :: TimeStamp
= basic string
with inj_TimeStamp, prj_TimeStamp
test :: TestRec
= record
created_at :: TimeStamp
-----
$(generate tests)
-- created_at parses with:
-- parseTime defaultTimeLocale "%Y-%m-%d %H:%M:%S%Q" a
type TimeStamp = Maybe UTCTime
inj_TimeStamp :: REP__TimeStamp -> ParserWithErrs TimeStamp
inj_TimeStamp (REP__TimeStamp as) =
return $ parseTime defaultTimeLocale "%Y-%m-%d %H:%M:%S%Q" (Text.unpack as)
prj_TimeStamp :: TimeStamp -> REP__TimeStamp
prj_TimeStamp (Just mp) = REP__TimeStamp $
Text.pack $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S%Q" mp
prj_TimeStamp Nothing = REP__TimeStamp $
Text.pack ""
$(generateAPITools tests [enumTool, jsonTool])
But, when I use it like this, I still get the format error:
λ import qualified Data.ByteString.Lazy as LBS
λ import Mytest.Types
λ let a = "{ \"created_at\": \"2014-09-10 14:06:48.13972\" }" :: LBS.ByteString
λ decodeWithErrs a :: Either [(JSONError, Position)] TestRec
Left [(BadFormat FmtUTC "UTC" "2014-09-10 14:06:48.13972",[InField "created_at"])]
It seems its not using the functions provided to parse the result at
all, if I put in some bogus stuff the conversion functions and set the
type of TimeStamp to Text, the created_at string appears in the output:
inj_TimeStamp :: REP__TimeStamp -> ParserWithErrs TimeStamp
inj_TimeStamp (REP__TimeStamp _) =
return $ Text.pack "heheheheh"
prj_TimeStamp :: TimeStamp -> REP__TimeStamp
prj_TimeStamp _ = REP__TimeStamp $ Text.pack "Hohoho"
λ let a = "{ \"created_at\": \"2014-09-10 14:06:48.13972\" }" :: LBS.ByteString
λ decodeWithErrs a :: Either [(JSONError, Position)] TextRec
Right (TextRec {_test_created_at = "2014-09-10 14:06:48.13972"})
I'm probably missing something really simple here, but maybe you can
spot it quicker than I do.. I'll investigate more when I'm back home
anyways.
Thanks for any hints!
k
Adam Gundry
Hi Karsten,
This isn't very well documented, but there is a (hidden) feature of api-tools that should do what you want. If you say something like
mt :: MyTime = basic string with inj_MyTime, prj_MyTime
then you can define your own type MyTime and give conversion functions inj_MyTime and prj_MyTime to convert back and forth from a newtype-wrapped Text. (In fact, you could probably use UTCTime as MyTime...). More precisely, api-tools will generate something like
newtype REP__MyTime = REP__MyTime Text
and you will need to implement
inj_MyTime :: REP__MyTime -> ParserWithErrs MyTime prj_MyTime :: MyTime -> REP__MyTime
I hope this helps, and further questions or documentation contributions are very welcome!
Cheers,
Adam
On 09/09/14 14:02, Karsten Gebbert wrote:
Hi All,
I have a question concerning the api-tools package.
Its not clear from the tests, sources or the tutorial how I can use other date/time formats that the default `utc` type can handle. I'm trying to wrap a JSON API that is not under my control, so I have to adhere to whatever I get back from it. Could anybody with experience with the package point me to some example, relevant bits in the sources or a tip how to do it?
I'm planning to create some more documentation around the package to contribute back once I figured out a few more details, because I think its quite a useful abstraction when dealing with (foreign) APIs IMO.
Thanks already for any hints,
karsten
-- Adam Gundry, Haskell Consultant Well-Typed LLP, http://www.well-typed.com/