@@ -272,33 +272,41 @@ class ConsToJSON f where
272272 consToEncoding :: Options -> f a -> B.Builder
273273
274274class ConsToJSON' f isRecord where
275− consToJSON' :: Options -> f a -> Tagged isRecord Value
276− consToEncoding' :: Options -> f a -> Tagged isRecord B.Builder
277−
275+ consToJSON' :: Options -> Bool -- ^ Are we a record with one field
276+ -> f a -> Tagged isRecord Value
277+ consToEncoding' :: Options -> Bool -- ^ Are we a record with one field
278+ -> f a -> Tagged isRecord B.Builder
279+
278280instance ( IsRecord f isRecord
279281 , ConsToJSON' f isRecord ) => ConsToJSON f where
280282 consToJSON opts = (unTagged :: Tagged isRecord Value -> Value)
281− . consToJSON' opts
283+ . consToJSON' opts (isUnary (undefined :: f a))
282284 {-# INLINE consToJSON #-}
283285
284286 consToEncoding opts = (unTagged :: Tagged isRecord B.Builder -> B.Builder)
285− . consToEncoding' opts
287+ . consToEncoding' opts (isUnary (undefined :: f a))
286288 {-# INLINE consToEncoding #-}
287289
288290instance (RecordTo f) => ConsToJSON' f True where
289− consToJSON' opts = Tagged . object . toList . recordToPairs opts
291+ consToJSON' opts isUn f = let
292+ vals = toList $ recordToPairs opts f
293+ in case (unwrapUnaryRecords opts,isUn,vals) of
294+ (True,True,[(_,val)]) -> Tagged val
295+ _ -> Tagged $ object vals
290296 {-# INLINE consToJSON' #-}
291297
292− consToEncoding' opts x = Tagged $
293− B.char7 '{' <>
294− recordToEncoding opts x <>
295− B.char7 '}'
298+ consToEncoding' opts isUn x
299+ | (True,True) <- (unwrapUnaryRecords opts,isUn) = Tagged $ recordToEncoding opts x
300+ | otherwise = Tagged $
301+ B.char7 '{' <>
302+ recordToEncoding opts x <>
303+ B.char7 '}'
296304 {-# INLINE consToEncoding' #-}
297305
298306instance GToJSON f => ConsToJSON' f False where
299− consToJSON' opts = Tagged . gToJSON opts
307+ consToJSON' opts _ = Tagged . gToJSON opts
300308 {-# INLINE consToJSON' #-}
301− consToEncoding' opts = Tagged . gbuilder opts
309+ consToEncoding' opts _ = Tagged . gbuilder opts
302310 {-# INLINE consToEncoding' #-}
303311
304312--------------------------------------------------------------------------------
@@ -585,7 +593,7 @@ instance ( IsRecord f isRecord
585593 {-# INLINE parseFromTaggedObject' #-}
586594
587595instance (FromRecord f) => FromTaggedObject'' f True where
588− parseFromTaggedObject'' opts _ = Tagged . parseRecord opts
596+ parseFromTaggedObject'' opts _ = Tagged . parseRecord opts Nothing
589597 {-# INLINE parseFromTaggedObject'' #-}
590598
591599instance (GFromJSON f) => FromTaggedObject'' f False where
@@ -599,42 +607,56 @@ class ConsFromJSON f where
599607 consParseJSON :: Options -> Value -> Parser (f a)
600608
601609class ConsFromJSON' f isRecord where
602− consParseJSON' :: Options -> Value -> Tagged isRecord (Parser (f a))
610+ consParseJSON' :: Options -> (Maybe Text) -- ^ A dummy label
611+ -- (Nothing to use proper label)
612+ -> Value -> Tagged isRecord (Parser (f a))
603613
604614instance ( IsRecord f isRecord
605615 , ConsFromJSON' f isRecord
606616 ) => ConsFromJSON f where
607− consParseJSON opts = (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
608− . consParseJSON' opts
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")
621+ _ ->(v,Nothing)
622+ in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
623+ $ consParseJSON' opts lab v2
609624 {-# INLINE consParseJSON #-}
610625
626+
611627instance (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)
613630 {-# INLINE consParseJSON' #-}
614631
615632instance (GFromJSON f) => ConsFromJSON' f False where
616− consParseJSON' opts = Tagged . gParseJSON opts
633+ consParseJSON' opts _ = Tagged . gParseJSON opts
617634 {-# INLINE consParseJSON' #-}
618635
619636--------------------------------------------------------------------------------
620637
621638class FromRecord f where
622− parseRecord :: Options -> Object -> Parser (f a)
639+ parseRecord :: Options -> (Maybe Text) -- ^ A dummy label
640+ -- (Nothing to use proper label)
641+ -> Object -> Parser (f a)
623642
624643instance (FromRecord a, FromRecord b) => FromRecord (a :*: b) where
625− parseRecord opts obj = (:*:) <$> parseRecord opts obj
626− <*> parseRecord opts obj
644+ parseRecord opts _ obj = (:*:) <$> parseRecord opts Nothing obj
645+ <*> parseRecord opts Nothing obj
627646 {-# INLINE parseRecord #-}
628647
629648instance (Selector s, GFromJSON a) => FromRecord (S1 s a) where
630− parseRecord opts = maybe (notFound label) (gParseJSON opts)
631− . H.lookup (pack label)
649+ parseRecord opts (Just lab) = maybe (notFound $ unpack lab)
650+ (gParseJSON opts) . H.lookup lab
651+ parseRecord opts Nothing = maybe (notFound label)
652+ (gParseJSON opts) . H.lookup (pack label)
632653 where
633654 label = fieldLabelModifier opts $ selName (undefined :: t s a p)
634655 {-# INLINE parseRecord #-}
635656
636657instance (Selector s, FromJSON a) => FromRecord (S1 s (K1 i (Maybe a))) where
637− parseRecord opts obj = (M1 . K1) <$> obj .:? pack label
658+ parseRecord _ (Just lab) obj = (M1 . K1) <$> obj .:? lab
659+ parseRecord opts Nothing obj = (M1 . K1) <$> obj .:? pack label
638660 where
639661 label = fieldLabelModifier opts $
640662 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
695717--------------------------------------------------------------------------------
696718
697719class IsRecord (f :: * -> *) isRecord | f -> isRecord
720+ where
721+ isUnary :: f a -> Bool
722+ isUnary = const True
698723
699724instance (IsRecord f isRecord) => IsRecord (f :*: g) isRecord
725+ where isUnary = const False
700726instance IsRecord (M1 S NoSelector f) False
701727instance (IsRecord f isRecord) => IsRecord (M1 S c f) isRecord
702728instance IsRecord (K1 i c) True
703729instance IsRecord U1 False
730+ where isUnary = const False
704731
705732--------------------------------------------------------------------------------
706733