on master help sign in
Add NonEmpty instances
commit66bbc1972847d1c701281e883328e7959b6e3a77 authorOleg Grenrus <oleg.grenrus@iki.fi> dateTue 9 Feb 2016, 11:47 (11 years ago) parent674eee5
4 files changed+25−1
Data/Aeson/Types/Instances.hs+15 aeson.cabal+4−1 tests/Instances.hs+4 tests/Properties.hs+2
Data/Aeson/Types/Instances.hs+15
@@ -71,6 +71,7 @@ import Data.Foldable (toList)
7171import Data.Functor.Identity (Identity(..))
7272import Data.Hashable (Hashable(..))
7373import Data.Int (Int8, Int16, Int32, Int64)
74+import Data.List.NonEmpty (NonEmpty(..))
7475import Data.Maybe (fromMaybe)
7576import Data.Monoid ((<>))
7677import Data.Monoid (Dual(..), First(..), Last(..))
@@ -491,6 +492,20 @@ instance FromJSON LT.Text where
491492 parseJSON = withText "Lazy Text" $ pure . LT.fromStrict
492493 {-# INLINE parseJSON #-}
493494
495+instance (ToJSON a) => ToJSON (NonEmpty a) where
496+ toJSON = toJSON . toList
497+ {-# INLINE toJSON #-}
498+
499+ toEncoding = toEncoding . toList
500+ {-# INLINE toEncoding #-}
501+
502+instance (FromJSON a) => FromJSON (NonEmpty a) where
503+ parseJSON = withArray "NonEmpty a" $
504+ (>>= ne) . Tr.sequence . zipWith parseIndexedJSON [0..] . V.toList
505+ where
506+ ne [] = fail "Expected a NonEmpty but got an empty list"
507+ ne (x:xs) = pure (x :| xs)
508+
494509instance OVERLAPPABLE_ (ToJSON a) => ToJSON [a] where
495510 toJSON = Array . V.fromList . map toJSON
496511 {-# INLINE toJSON #-}
aeson.cabal+4−1
@@ -145,7 +145,7 @@ test-suite tests
145145
146146 build-depends:
147147 HUnit,
148− QuickCheck >= 2.7,
148+ QuickCheck >= 2.7 && <2.8.3,
149149 aeson,
150150 attoparsec,
151151 base,
@@ -162,6 +162,9 @@ test-suite tests
162162 vector,
163163 quickcheck-instances >=0.3.12
164164
165+ if !impl(ghc >= 8.0)
166+ build-depends: semigroups >= 0.16.1
167+
165168 if flag(old-locale)
166169 build-depends: time < 1.5, old-locale
167170 else
tests/Instances.hs+4
@@ -14,6 +14,7 @@ import Test.QuickCheck (Arbitrary(..), getNonNegative, elements,
1414 listOf1, oneof, resize)
1515import Data.Time.Clock (UTCTime(..))
1616import Data.Time (ZonedTime(..), TimeZone(..))
17+import Data.List.NonEmpty (NonEmpty(..))
1718import Data.Version
1819import Data.Aeson.Types
1920import Control.Applicative
@@ -136,6 +137,9 @@ instance (ApproxEq a) => ApproxEq [a] where
136137instance Arbitrary Version where
137138 arbitrary = makeVersion . fmap getNonNegative <$> resize 4 (listOf1 arbitrary)
138139
140+instance Arbitrary a => Arbitrary (NonEmpty a) where
141+ arbitrary = (:|) <$> arbitrary <*> arbitrary
142+
139143-- Version tags are deprecated, so we avoid using them in the Arbitrary
140144-- instance. However, the recommended constructor 'makeVersion' is not
141145-- exported by "Data.Version" until base-4.8.0.0. For previous versions,
tests/Properties.hs+2
@@ -9,6 +9,7 @@ import Data.Aeson.Parser (value)
99import Data.Aeson.Types
1010import Data.ByteString.Builder (toLazyByteString)
1111import Data.Int (Int8)
12+import Data.List.NonEmpty (NonEmpty)
1213import Data.Time (Day, LocalTime, NominalDiffTime, TimeOfDay, UTCTime,
1314 ZonedTime)
1415import Data.Version (Version)
@@ -127,6 +128,7 @@ tests = testGroup "properties" [
127128 testProperty "Bool" $ roundTripEq True
128129 , testProperty "Double" $ roundTripEq (1 :: Approx Double)
129130 , testProperty "Int" $ roundTripEq (1 :: Int)
131+ , testProperty "NonEmpty Char" $ roundTripEq (undefined :: NonEmpty Char)
130132 , testProperty "Integer" $ roundTripEq (1 :: Integer)
131133 , testProperty "String" $ roundTripEq ("" :: String)
132134 , testProperty "Text" $ roundTripEq T.empty