重写Data.Aeson只处理我的记录的一个字段 [英] Override how Data.Aeson handles only one field of my record

查看:145
本文介绍了重写Data.Aeson只处理我的记录的一个字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆