Разбор встроенного JSON с Aeson - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь разобрать встроенный JSON вида

{
  "foo":"bar",
  "baz":"\{\"somekey\":\"someval\"\}"
}

с Эзоном в Хаскеле.Вот мои типы:

data BaseType = BaseType { foo :: String, baz :: EmbeddedType } deriving(Show)

instance FromJSON BaseType where
  parseJSON = withObject "BaseType" $ \o -> do
    foo <- o .: "foo"
    baz <- o .: "baz"
    return $ BaseType { foo=foo, baz=baz }

data EmbeddedType = EmbeddedType { somekey :: String }

instance FromJSON EmbeddedType where
  parseJSON = withObject "EmbeddedType" $ \o -> do
    somekey <- o .: "somekey"
    return $ EmbeddedType {somekey=somekey}

Очевидно, что экземпляр FromJSON для BaseType не работает, так как он рассматривает его как Value String вместо большего количества JSON для его анализа.Я пытался найти способ использовать decodeEither в моем экземпляре FromJSON BaseType, но для этого потребовалось немного черной магии для преобразования из String в ByteString, и я чувствую, что должен быть более аккуратный способ, возможно,относящиеся к withEmbeddedJSON.

Как я могу сделать это правильно?

1 Ответ

0 голосов
/ 19 декабря 2018

Полагаю, это будет что-то вроде этого (не проверено):

instance FromJSON BaseType where
  parseJSON = withObject "BaseType" $ \o -> do
    foo <- o .: "foo"
    bazText <- o .: "baz"
    baz <- withEmbeddedJSON "EmbeddedType" parseJSON (String bazText)
    return $ BaseType { foo=foo, baz=baz }

Или вы можете рассмотреть возможность перемещения вызова на withEmbeddedJSON в EmbeddedType экземпляр;тогда o .: "baz" должен просто работать в экземпляре BaseType, за счет того, что у него больше нет дескриптора синтаксического анализатора, который просто выполняет синтаксический анализ EmbeddedType без удаления строки:

instance FromJSON BaseType where
  parseJSON = withObject "BaseType" $ \o -> do
    foo <- o .: "foo"
    baz <- o .: "baz"
    return $ BaseType { foo=foo, baz=baz }

instance FromJSON EmbeddedType where
  parseJSON = withEmbeddedJSON "EmbeddedType" . withObject "EmbeddedType" $ \o -> do
    somekey <- o .: "somekey"
    return $ EmbeddedType {somekey=somekey}
...