У меня сложная вложенная структура данных, которую я хотел бы преобразовать в JSON различными способами в зависимости от заданного контекста.Мой вариант использования состоит в том, что мой сервер содержит полное состояние состояния мира, но в зависимости от того, какой клиент его запрашивает, я хочу предоставить отредактированную копию.В идеале я хотел бы написать что-то вроде:
instance ToJSON MyNestedType where
toJSON x = do
currentUser <- ask
return $ if owner x == currentUser then (defaultToJson x) else (toJSON "REDACTED")
encodeWithReader (UserId 123) myDataStructure
Глядя на тип toJSON :: a -> Value
, это кажется невозможным для простого Aeson.Что было бы хорошим вариантом для этого?Несколько вариантов, о которых я думал:
Реализация моего собственного класса типов ToJSONReader
, и реализация по умолчанию, которая просто проходит к ToJSON
и переопределение для типов, которые требуют редактирования,Что-то вроде (это не компилируется, просто псевдокод. На самом деле я не знаю, как сделать эту работу.):
class ToJSONReader a where
toJSONReader :: a -> Reader b Value
instance ToJSON a => ToJSONReader a where
toJSONReader x = return $ toJSON x
instance ToJSONReader MyNestedType where
toJSONReader x = do
currentUser <- ask
return $ if owner x == currentUser then (toJSON x) else (toJSON "REDACTED")
Вместо того, чтобы использовать encode
напрямую, используйтеtoJSON
чтобы получить промежуточное значение Value
, затем напишите код для редактирования этого (типа брутто).
- Расширьте мой тип, включив в него теги для редактирования, а затем предварительно обработайте копию типа передпреобразование в JSON.
- Создайте новый сложный родительский тип
RedactedMyType
и продублируйте структуру исходного типа, но при необходимости добавьте в отредактированные параметры в ADT.Довольно брутто также.
У кого-нибудь есть какие-либо рекомендации?