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:
parent
bf1e7398a1
commit
a3921134a7
17
src/JRec.hs
17
src/JRec.hs
@ -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
|
||||
--
|
||||
|
@ -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.
|
||||
|
@ -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)))
|
||||
|
Loading…
Reference in New Issue
Block a user