]> gitweb.michael.orlitzky.com - dead/htsn-import.git/blobdiff - src/TSN/Picklers.hs
Allow "TBA" laps in TSN.XML.AutoRacingSchedule.
[dead/htsn-import.git] / src / TSN / Picklers.hs
index 5e620699bbfdc43e53181511493be47f433349ba..4f0020b6ad167123c10a66224a0b5092f09b8489 100644 (file)
@@ -1,9 +1,12 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
 -- | (Un)picklers for data types present in The Sports Network XML
 --   feed.
 --
 module TSN.Picklers (
   pickler_tests,
   xp_ambiguous_time,
+  xp_attr_option,
   xp_date,
   xp_date_padded,
   xp_datetime,
@@ -11,6 +14,7 @@ module TSN.Picklers (
   xp_earnings,
   xp_fracpart_only_double,
   xp_gamedate,
+  xp_tba_int,
   xp_tba_time,
   xp_time,
   xp_time_dots,
@@ -448,6 +452,46 @@ xp_tba_time =
     from_time (Just t) = formatTime defaultTimeLocale time_format t
 
 
+-- | (Un)pickle a 'Int', allowing for a value of \"TBA\" (which gets
+--   translated to 'Nothing').
+--
+--   /Examples/:
+--
+--   A failed parse will return 'Nothing':
+--
+--   >>> let tn = text_node "YO"
+--   >>> unpickleDoc xp_tba_int tn
+--   Just Nothing
+--
+--   And so will parsing a \"TBA\":
+--
+--   >>> let tn = text_node "TBA"
+--   >>> unpickleDoc xp_tba_int tn
+--   Just Nothing
+--
+--   But re-pickling 'Nothing' gives only \"TBA\":
+--
+--   >>> pickleDoc xp_tba_int Nothing
+--   NTree (XTag "/" []) [NTree (XText "TBA") []]
+--
+--   A normal integer is also parsed successfully, of course:
+--
+--   >>> let tn = text_node "110"
+--   >>> unpickleDoc xp_tba_int tn
+--   Just (Just 110)
+--
+xp_tba_int :: PU (Maybe Int)
+xp_tba_int =
+  (to_int, from_int) `xpWrap` xpText
+  where
+    to_int :: String -> Maybe Int
+    to_int = readMaybe
+
+    from_int :: Maybe Int -> String
+    from_int Nothing = "TBA"
+    from_int (Just t) = show t
+
+
 
 -- | (Un)pickle the \<time_stamp\> element format to/from a 'UTCTime'.
 --   The time_stamp elements look something like,
@@ -569,6 +613,23 @@ xp_early_line_date =
         fmt = "%A, %B %-d" ++ upper_suffix ++ " (" ++ date_format_padded ++ ")"
 
 
+-- | This is a replacement for @xpOption xpFoo@ within an 'xpAttr'.
+--   There's a bug <https://github.com/UweSchmidt/hxt/issues/39> in
+--   newer versions of HXT that prevents us from using the usual
+--   'xpOption' solution, so this is our stopgap. It should work on
+--   any type that can be unpickled with a plain read/show.
+--
+xp_attr_option ::  forall a. (Read a, Show a) => PU (Maybe a)
+xp_attr_option =
+  (to_a, from_a) `xpWrap` xpText
+  where
+    to_a :: String -> Maybe a
+    to_a = readMaybe
+
+    from_a :: Maybe a -> String
+    from_a Nothing  = ""
+    from_a (Just x) = show x
+
 
 -- | Create an 'XmlTree' containing only the given text. This is
 --   useful for testing (un)picklers, where we don't want to have to