parseCompactStruct :: Parser (Map.HashMap Int16 (LT.Text, ThriftVal))
parseCompactStruct = Map.fromList <$> parseFields 0
  where
    parseFields :: Int16 -> Parser [(Int16, (LT.Text, ThriftVal))]
    parseFields lastId = do
      w <- P.anyWord8
      if w == 0x00
        then return []
        else do
          let ty = typeFrom (w .&. 0x0F)
              modifier = (w .&. 0xF0) `shiftR` 4
          fid <- if modifier /= 0
                 then return (lastId + fromIntegral modifier)
                 else parseVarint zigZagToI16
          val <- if ty == T_BOOL
                 then return (TBool $ (w .&. 0x0F) == 0x01)
                 else parseCompactValue ty
          ((fid, (LT.empty, val)) : ) <$> parseFields fid
parseCompactStruct :: Parser (Map.HashMap Int16 (LT.Text, ThriftVal))
parseCompactStruct = Map.fromList <$> parseFields 0
  where
    parseFields :: Int16 -> Parser [(Int16, (LT.Text, ThriftVal))]
    parseFields lastId = do
      w <- P.anyWord8
      if w == 0x00
        then return []
        else do
          let ty = typeFrom (w .&. 0x0F)
              modifier = (w .&. 0xF0) `shiftR` 4
          fid <- if modifier /= 0
                 then return (lastId + fromIntegral modifier)
                 else parseVarint zigZagToI16
          val <- if ty == T_BOOL
                 then return (TBool $ (w .&. 0x0F) == 0x01)
                 else parseCompactValue ty
          ((fid, (LT.empty, val)) : ) <$> parseFields fid
parseCompactStruct = Map.fromList <$> parseFields 0
  where
    parseFields :: Int16 -> Parser [(Int16, (LT.Text, ThriftVal))]
    parseFields lastId = do
      w <- P.anyWord8
      if w == 0x00
        then return []
        else do
          let ty = typeFrom (w .&. 0x0F)
              modifier = (w .&. 0xF0) `shiftR` 4
          fid <- if modifier /= 0
                 then return (lastId + fromIntegral modifier)
                 else parseVarint zigZagToI16
          val <- if ty == T_BOOL
                 then return (TBool $ (w .&. 0x0F) == 0x01)
                 else parseCompactValue ty
          ((fid, (LT.empty, val)) : ) <$> parseFields fid