重写Data.Aeson只处理我的记录的一个字段 [英] Override how Data.Aeson handles only one field of my record
问题描述
data Course = Course {
id :: Maybe文本,
名称::文本,
删除:: Bool
}派生(显示,通用)
实例FromJSON课程
实例ToJSON课程
我希望允许删除
为可选项序列化的JSON结构,但不在我的应用程序中。如果解析时未指定,那么我想将
删除
设置为 False
。
我可以为 FromJSON
写一个手动实例,但我不想写出来所有的领域。我想声明如何处理删除,并让自动实例处理其他所有内容。
我会如何做到这一点?
据我所知不是自定义泛型实例的方法,但是您可以以不同的方式构造您的类型:
数据课程=课程
{courseId :: Maybe Text - 不要使用`id`,它已经是一个函数
,name :: Text
}派生(Show,Generic)
data可删除a =可删除
{已删除:: Bool
,item :: a
}派生(显示)
实例FromJSON课程
实例ToJSON课程
实例FromJSON a => FromJSON(可删除的a)其中
parseJSON(Object v)= do
i < - parseJSON(Object v)
d < - v。:? deleted。!= False
return $ Deletable di
parseJSON _ = mzero
现在你可以做
> let noDeleted ={\name \:\Math \,\courseId\:\12345\}:: Text
> let withDeleted ={\name \:\Math \,\courseId\:\12345\,\deleted\:true}::文本
>解码noDeleted ::也许(可删除的课程)
Just(Deletable {deleted = False,item = Course {courseId = Just12345,name =Math}})
>解码noDeleted ::也许课程
只是(课程{courseId =只是12345,名称=数学})
> decodeDeleted :: Maybe(Deletable Course)
Just(Deletable {deleted = True,item = Course {courseId = Just12345,name =Math}})
>解码withDeleted ::也许课程
Just(Course {courseId = Just12345,name =Math})
现在,您可以选择在需要时将课程标记为可删除,并且 FromJSON
实例处理所有事情。
I am making a REST API for university courses:
data Course = Course {
id :: Maybe Text,
name :: Text,
deleted :: Bool
} deriving(Show, Generic)
instance FromJSON Course
instance ToJSON Course
I would like to allow deleted
to be optional in the serialized JSON structure, but not in my application. I want to set deleted
to False
if it isn't specified when parsing.
I could write a manual instance for FromJSON
, but I don't want to have to write it out for all the fields. I want to declare how deleted is handled and let the automatic instance handle everything else.
How would I do this?
To my knowledge there is not a way to customize the generic instance, but you could structure your type a bit differently:
data Course = Course
{ courseId :: Maybe Text -- Don't use `id`, it's already a function
, name :: Text
} deriving (Show, Generic)
data Deletable a = Deletable
{ deleted :: Bool
, item :: a
} deriving (Show)
instance FromJSON Course
instance ToJSON Course
instance FromJSON a => FromJSON (Deletable a) where
parseJSON (Object v) = do
i <- parseJSON (Object v)
d <- v .:? "deleted" .!= False
return $ Deletable d i
parseJSON _ = mzero
Now you can do
> let noDeleted = "{\"name\":\"Math\",\"courseId\":\"12345\"}" :: Text
> let withDeleted = "{\"name\":\"Math\",\"courseId\":\"12345\",\"deleted\":true}" :: Text
> decode noDeleted :: Maybe (Deletable Course)
Just (Deletable {deleted = False, item = Course {courseId = Just "12345", name = "Math"}})
> decode noDeleted :: Maybe Course
Just (Course {courseId = Just "12345", name = "Math"})
> decode withDeleted :: Maybe (Deletable Course)
Just (Deletable {deleted = True, item = Course {courseId = Just "12345", name = "Math"}})
> decode withDeleted :: Maybe Course
Just (Course {courseId = Just "12345", name = "Math"})
And now you can just optionally tag a course as deletable when you need it, and the FromJSON
instances take care of everything.
这篇关于重写Data.Aeson只处理我的记录的一个字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!