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 <adam@well-typed.com> writes:
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/