1
1
mirror of https://github.com/juspay/jrec.git synced 2024-10-05 22:57:13 +03:00

omit Nothing while encoding to json

This commit is contained in:
kana-sama 2020-10-22 18:21:52 +03:00
parent bf1e7398a1
commit a3921134a7
3 changed files with 33 additions and 17 deletions

View File

@ -10,7 +10,7 @@ module JRec
append,
union,
insert,
insertOrSet
insertOrSet,
)
where
@ -63,8 +63,8 @@ append = R.combine
-- Merges records, removing duplicates
--
-- Left-biased. Does not sort.
--
-- Left-biased. Does not sort.
--
-- O(n * m) type check complexity.
union ::
forall lhs rhs res.
@ -83,18 +83,19 @@ union = R.union
-- | Insert a field into a record that does not already contain it
--
-- O(n) type check complexity.
insert ::
forall label value lts res.
insert ::
forall label value lts res.
( KnownNat (1 + R.RecSize lts),
KnownNat (R.RecSize lts),
KnownSymbol label,
R.RecCopy lts lts res,
res ~ ((label := value) : lts),
R.RemoveAccessTo label lts ~ lts
) =>
) =>
label := value ->
Rec lts -> Rec res
insert = R.combine . Rec
Rec lts ->
Rec res
insert = R.combine . Rec
-- | Insert a field into a record. Set it if it already exists
--

View File

@ -32,6 +32,7 @@ import qualified Control.Monad.State as S
import Data.Aeson
import Data.Aeson.Types (Parser)
import Data.Constraint
import Data.Maybe (catMaybes)
import Data.Proxy
import qualified Data.Text as T
import Data.Typeable
@ -115,7 +116,7 @@ instance RecEq lts lts => Eq (Rec lts) where
#ifdef WITH_AESON
instance
( RecApply lts lts ToJSON
( RecApply lts lts EncodeField
) =>
ToJSON (Rec lts)
where
@ -124,6 +125,7 @@ instance
instance (RecSize lts ~ s, KnownNat s, RecJsonParse lts) => FromJSON (Rec lts) where
parseJSON = recJsonParser defaultJSONOptions
#endif
instance RecNfData lts lts => NFData (Rec lts) where
@ -552,13 +554,26 @@ reflectRecFold _ f r =
showRec :: forall lts. (RecApply lts lts Show) => Rec lts -> [(String, String)]
showRec = reflectRec @Show Proxy (\k v -> (k, show v))
recToValue :: forall lts. (RecApply lts lts ToJSON) => JSONOptions -> Rec lts -> Value
recToValue options r =
object $ reflectRec @ToJSON Proxy (\k v -> (T.pack (fieldTransform options k), toJSON v)) r
class ToJSON a => EncodeField a where
encodeField :: a -> Maybe Value
encodeKV :: T.Text -> a -> Series
recToEncoding :: forall lts. (RecApply lts lts ToJSON) => JSONOptions -> Rec lts -> Encoding
instance ToJSON a => EncodeField a where
encodeField = pure . toJSON
encodeKV = (.=)
instance {-# OVERLAPS #-} ToJSON a => EncodeField (Maybe a) where
encodeField = fmap toJSON
encodeKV _ Nothing = mempty
encodeKV k v = k .= v
recToValue :: forall lts. (RecApply lts lts EncodeField) => JSONOptions -> Rec lts -> Value
recToValue options r =
object $ catMaybes $ reflectRec @EncodeField Proxy (\k v -> (T.pack (fieldTransform options k),) <$> encodeField v) r
recToEncoding :: forall lts. (RecApply lts lts EncodeField) => JSONOptions -> Rec lts -> Encoding
recToEncoding options r =
pairs $ mconcat $ reflectRec @ToJSON Proxy (\k v -> (T.pack (fieldTransform options k) .= v)) r
pairs $ mconcat $ reflectRec @EncodeField Proxy (\k v -> (T.pack (fieldTransform options k) `encodeKV` v)) r
recJsonParser ::
forall lts s.

View File

@ -91,14 +91,14 @@ spec = do
describe "optional fields" $ do
it "encode" $ do
encode (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
`shouldBe` "{\"a\":1,\"b\":null}"
`shouldBe` "{\"a\":1}"
it "encode" $ do
encode (Rec (#a := (1 :: Int), #b := (Just 2 :: Maybe Int)))
`shouldBe` "{\"a\":1,\"b\":2}"
it "decode" $ do
decode "{\"a\": 1, \"b\": null}"
`shouldBe` Just (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
decode "{\"a\": 1}"
`shouldBe` Just (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
decode "{\"a\": 1, \"b\": null}"
`shouldBe` Just (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
decode "{\"a\": 1, \"b\": 2}"
`shouldBe` Just (Rec (#a := (1 :: Int), #b := (Just 2 :: Maybe Int)))