@@ -272,33 +272,41 @@ class ConsToJSON f where
272 consToEncoding :: Options -> f a -> B.Builder
272 consToEncoding :: Options -> f a -> B.Builder
274class ConsToJSON' f isRecord where
274class ConsToJSON' f isRecord where
275+ consToJSON' :: Options -> Bool -- ^ Are we a record with one field
275− consToJSON' :: Options -> f a -> Tagged isRecord Value
276+ -> f a -> Tagged isRecord Value
277+ consToEncoding' :: Options -> Bool -- ^ Are we a record with one field
276− consToEncoding' :: Options -> f a -> Tagged isRecord B.Builder
278+ -> f a -> Tagged isRecord B.Builder
278instance ( IsRecord f isRecord
280instance ( IsRecord f isRecord
279 , ConsToJSON' f isRecord ) => ConsToJSON f where
281 , ConsToJSON' f isRecord ) => ConsToJSON f where
280 consToJSON opts = (unTagged :: Tagged isRecord Value -> Value)
282 consToJSON opts = (unTagged :: Tagged isRecord Value -> Value)
281− . consToJSON' opts
283+ . consToJSON' opts (isUnary (undefined :: f a))
282 {-# INLINE consToJSON #-}
284 {-# INLINE consToJSON #-}
284 consToEncoding opts = (unTagged :: Tagged isRecord B.Builder -> B.Builder)
286 consToEncoding opts = (unTagged :: Tagged isRecord B.Builder -> B.Builder)
285− . consToEncoding' opts
287+ . consToEncoding' opts (isUnary (undefined :: f a))
286 {-# INLINE consToEncoding #-}
288 {-# INLINE consToEncoding #-}
288instance (RecordTo f) => ConsToJSON' f True where
290instance (RecordTo f) => ConsToJSON' f True where
291+ consToJSON' opts isUn f = let
289− consToJSON' opts = Tagged . object . toList . recordToPairs opts
292+ vals = toList $ recordToPairs opts f
293+ in case (unwrapUnaryRecords opts,isUn,vals) of
294+ (True,True,[(_,val)]) -> Tagged val
295+ _ -> Tagged $ object vals
290 {-# INLINE consToJSON' #-}
296 {-# INLINE consToJSON' #-}
292− consToEncoding' opts x = Tagged $
298+ consToEncoding' opts isUn x
299+ | (True,True) <- (unwrapUnaryRecords opts,isUn) = Tagged $ recordToEncoding opts x
300+ | otherwise = Tagged $
293− B.char7 '{' <>
301+ B.char7 '{' <>
294− recordToEncoding opts x <>
302+ recordToEncoding opts x <>
295− B.char7 '}'
303+ B.char7 '}'
296 {-# INLINE consToEncoding' #-}
304 {-# INLINE consToEncoding' #-}
298instance GToJSON f => ConsToJSON' f False where
306instance GToJSON f => ConsToJSON' f False where
299− consToJSON' opts = Tagged . gToJSON opts
307+ consToJSON' opts _ = Tagged . gToJSON opts
300 {-# INLINE consToJSON' #-}
308 {-# INLINE consToJSON' #-}
301− consToEncoding' opts = Tagged . gbuilder opts
309+ consToEncoding' opts _ = Tagged . gbuilder opts
302 {-# INLINE consToEncoding' #-}
310 {-# INLINE consToEncoding' #-}
304--------------------------------------------------------------------------------
312--------------------------------------------------------------------------------
@@ -585,7 +593,7 @@ instance ( IsRecord f isRecord
585 {-# INLINE parseFromTaggedObject' #-}
593 {-# INLINE parseFromTaggedObject' #-}
587instance (FromRecord f) => FromTaggedObject'' f True where
595instance (FromRecord f) => FromTaggedObject'' f True where
588− parseFromTaggedObject'' opts _ = Tagged . parseRecord opts
596+ parseFromTaggedObject'' opts _ = Tagged . parseRecord opts Nothing
589 {-# INLINE parseFromTaggedObject'' #-}
597 {-# INLINE parseFromTaggedObject'' #-}
591instance (GFromJSON f) => FromTaggedObject'' f False where
599instance (GFromJSON f) => FromTaggedObject'' f False where
@@ -599,42 +607,56 @@ class ConsFromJSON f where
599 consParseJSON :: Options -> Value -> Parser (f a)
607 consParseJSON :: Options -> Value -> Parser (f a)
601class ConsFromJSON' f isRecord where
609class ConsFromJSON' f isRecord where
610+ consParseJSON' :: Options -> (Maybe Text) -- ^ A dummy label
611+ -- (Nothing to use proper label)
602− consParseJSON' :: Options -> Value -> Tagged isRecord (Parser (f a))
612+ -> Value -> Tagged isRecord (Parser (f a))
604instance ( IsRecord f isRecord
614instance ( IsRecord f isRecord
605 , ConsFromJSON' f isRecord
615 , ConsFromJSON' f isRecord
606 ) => ConsFromJSON f where
616 ) => ConsFromJSON f where
617+ consParseJSON opts v = let
618+ (v2,lab) = case (unwrapUnaryRecords opts,isUnary (undefined :: f a)) of
619+ -- use a dummy object with a dummy label
620+ (True,True) -> ((object [(pack "dummy",v)]),Just $ pack "dummy")
607− consParseJSON opts = (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
622+ in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
608− . consParseJSON' opts
623+ $ consParseJSON' opts lab v2
609 {-# INLINE consParseJSON #-}
624 {-# INLINE consParseJSON #-}
611instance (FromRecord f) => ConsFromJSON' f True where
627instance (FromRecord f) => ConsFromJSON' f True where
612− consParseJSON' opts = Tagged . (withObject "record (:*:)" $ parseRecord opts)
628+ consParseJSON' opts mlab = Tagged . (withObject "record (:*:)"
629+ $ parseRecord opts mlab)
613 {-# INLINE consParseJSON' #-}
630 {-# INLINE consParseJSON' #-}
615instance (GFromJSON f) => ConsFromJSON' f False where
632instance (GFromJSON f) => ConsFromJSON' f False where
616− consParseJSON' opts = Tagged . gParseJSON opts
633+ consParseJSON' opts _ = Tagged . gParseJSON opts
617 {-# INLINE consParseJSON' #-}
634 {-# INLINE consParseJSON' #-}
619--------------------------------------------------------------------------------
636--------------------------------------------------------------------------------
621class FromRecord f where
638class FromRecord f where
639+ parseRecord :: Options -> (Maybe Text) -- ^ A dummy label
640+ -- (Nothing to use proper label)
622− parseRecord :: Options -> Object -> Parser (f a)
641+ -> Object -> Parser (f a)
624instance (FromRecord a, FromRecord b) => FromRecord (a :*: b) where
643instance (FromRecord a, FromRecord b) => FromRecord (a :*: b) where
625− parseRecord opts obj = (:*:) <$> parseRecord opts obj
644+ parseRecord opts _ obj = (:*:) <$> parseRecord opts Nothing obj
626− <*> parseRecord opts obj
645+ <*> parseRecord opts Nothing obj
627 {-# INLINE parseRecord #-}
646 {-# INLINE parseRecord #-}
629instance (Selector s, GFromJSON a) => FromRecord (S1 s a) where
648instance (Selector s, GFromJSON a) => FromRecord (S1 s a) where
630− parseRecord opts = maybe (notFound label) (gParseJSON opts)
649+ parseRecord opts (Just lab) = maybe (notFound $ unpack lab)
650+ (gParseJSON opts) . H.lookup lab
651+ parseRecord opts Nothing = maybe (notFound label)
631− . H.lookup (pack label)
652+ (gParseJSON opts) . H.lookup (pack label)
633 label = fieldLabelModifier opts $ selName (undefined :: t s a p)
654 label = fieldLabelModifier opts $ selName (undefined :: t s a p)
634 {-# INLINE parseRecord #-}
655 {-# INLINE parseRecord #-}
636instance (Selector s, FromJSON a) => FromRecord (S1 s (K1 i (Maybe a))) where
657instance (Selector s, FromJSON a) => FromRecord (S1 s (K1 i (Maybe a))) where
658+ parseRecord _ (Just lab) obj = (M1 . K1) <$> obj .:? lab
637− parseRecord opts obj = (M1 . K1) <$> obj .:? pack label
659+ parseRecord opts Nothing obj = (M1 . K1) <$> obj .:? pack label
639 label = fieldLabelModifier opts $
661 label = fieldLabelModifier opts $
640 selName (undefined :: t s (K1 i (Maybe a)) p)
662 selName (undefined :: t s (K1 i (Maybe a)) p)
@@ -695,12 +717,17 @@ instance (Constructor c, GFromJSON a, ConsFromJSON a) => FromPair (C1 c a) where
695--------------------------------------------------------------------------------
717--------------------------------------------------------------------------------
697class IsRecord (f :: * -> *) isRecord | f -> isRecord
719class IsRecord (f :: * -> *) isRecord | f -> isRecord
721+ isUnary :: f a -> Bool
722+ isUnary = const True
699instance (IsRecord f isRecord) => IsRecord (f :*: g) isRecord
724instance (IsRecord f isRecord) => IsRecord (f :*: g) isRecord
725+ where isUnary = const False
700instance IsRecord (M1 S NoSelector f) False
726instance IsRecord (M1 S NoSelector f) False
701instance (IsRecord f isRecord) => IsRecord (M1 S c f) isRecord
727instance (IsRecord f isRecord) => IsRecord (M1 S c f) isRecord
702instance IsRecord (K1 i c) True
728instance IsRecord (K1 i c) True
703instance IsRecord U1 False
729instance IsRecord U1 False
730+ where isUnary = const False
705--------------------------------------------------------------------------------
732--------------------------------------------------------------------------------