X-Git-Url: http://gitweb.michael.orlitzky.com/?p=dead%2Fhtsn-import.git;a=blobdiff_plain;f=src%2FTSN%2FParse.hs;h=d707f5fd9575a4d2945f0285204145e0b44b5117;hp=9fe51259ddb518b46a83338fe55792226af7bbae;hb=b0fac40d71bca72312293eb33c33c0f0933d0a28;hpb=c8ec4174a46c44215ef9540a9b19b99323fb0717 diff --git a/src/TSN/Parse.hs b/src/TSN/Parse.hs index 9fe5125..d707f5f 100644 --- a/src/TSN/Parse.hs +++ b/src/TSN/Parse.hs @@ -113,6 +113,30 @@ parse_message_int child xmltree = +-- | Parse an optional 'Int' from a direct descendent of the +-- (top-level) \ element in an XmlTree. This is just like +-- 'parse_message_int', except we expect the element/value to be +-- missing sometimes. +-- +-- To handle the fact that the element/value is optional, we pattern +-- match on the 'ParseError' that comes back in case of failure. If +-- we didn't find anything, we turn that into a \"successful +-- nothing\". But if we find a value and it can't be parsed, we let +-- the error propagate, because that shouldn't happen. Of course, if +-- the parse worked, that's nice too: we wrap the parsed value in a +-- 'Just' and return that wrapped in a 'Right' +-- +parse_message_int_optional :: String + -> XmlTree + -> Either ParseError (Maybe Int) +parse_message_int_optional child xmltree = + case (parse_message_int child xmltree) of + Left (ParseNotFound _) -> Right Nothing + Left pm@(ParseMismatch {}) -> Left pm + Right whatever -> Right (Just whatever) + + + -- | Extract the \"XML_File_ID\" element from a document. If we fail -- to parse an XML_File_ID, we return an appropriate 'ParseError' -- wrapped in a 'Left' constructor. The reason should be one of two @@ -135,53 +159,21 @@ parse_xmlfid = parse_message_int "XML_File_ID" -- | Extract the \ element from within the top-level -- \ of a document. These appear in the "TSN.XML.GameInfo" --- documents. Unlike the \ and \ --- elements, the \ can be missing from GameInfo --- documents. So even the 'Right' value of the 'Either' can be --- \"missing\". There are two reasons that the parse might fail. --- --- 1. No such elements were found. This is expected sometimes, and --- should be returned as a 'Right' 'Nothing'. --- --- 2. An element was found, but it could not be read into an --- 'Int'. This is NOT expected, and will be returned as a --- 'ParseError', wrapped in a 'Left'. --- --- Most of implementation for this ('parse_message_int') is shared, --- but to handle the fact that game_id is optional, we pattern match --- on the 'ParseError' that comes back in case of failure. If we --- didn't find any game_id elements, we turn that into a --- \"successful nothing\". But if we find a game_id and it can't be --- parsed, we let the error propagate, because that shouldn't --- happen. Of course, if the parse worked, that's nice too: we wrap --- the parsed value in a 'Just' and return that wrapped in a 'Right' +-- documents. Unlike the \ elements, the \ +-- can be missing from GameInfo documents, so for our implementation +-- we use 'parse_message_int_optional' instead. -- parse_game_id :: XmlTree -> Either ParseError (Maybe Int) -parse_game_id xml = - case (parse_message_int "game_id" xml) of - Left (ParseNotFound _) -> Right Nothing - Left pm@(ParseMismatch {}) -> Left pm - Right whatever -> Right (Just whatever) +parse_game_id = parse_message_int_optional "game_id" -- | Extract the \ element from within the top-level --- \ of a document. These appear in the --- "TSN.XML.GameInfo" documents. If we fail to parse a schedule_id, --- we return the reason wrapped in an appropriate 'ParseError'. The reason --- should be one of two things: --- --- 1. No such elements were found. --- --- 2. An element was found, but it could not be read --- into an Int. --- --- Both of these are truly errors in the case of schedule_id. The --- implementation for this ('parse_message_int') is shared among a --- few functions. +-- \ of a document. Identical to 'parse_game_id' except +-- for the element name. -- -parse_schedule_id :: XmlTree -> Either ParseError Int -parse_schedule_id = parse_message_int "schedule_id" +parse_schedule_id :: XmlTree -> Either ParseError (Maybe Int) +parse_schedule_id = parse_message_int_optional "schedule_id" @@ -262,6 +254,7 @@ parse_tests = "TSN.Parse tests" [ test_parse_game_id, test_parse_missing_game_id, + test_parse_missing_schedule_id, test_parse_schedule_id, test_parse_xmlfid ] where @@ -312,3 +305,15 @@ test_parse_missing_game_id = let actual = parse_game_id xmltree let expected = Right Nothing actual @?= expected + + +-- | The schedule_id element can be missing, so we test that too. +-- +test_parse_missing_schedule_id :: TestTree +test_parse_missing_schedule_id = + testCase "missing schedule_id is not an error" $ do + let path = "test/xml/gameinfo/recapxml-no-game-schedule-ids.xml" + xmltree <- unsafe_read_document path + let actual = parse_schedule_id xmltree + let expected = Right Nothing + actual @?= expected