packages feed

aeson-possible 0.1.0.1 → 0.1.1.0

raw patch · 4 files changed

+69/−12 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Aeson.Possible: instance GHC.Base.Alternative Data.Aeson.Possible.Possible
- Data.Aeson.Possible: instance GHC.Base.Applicative Data.Aeson.Possible.Possible
- Data.Aeson.Possible: instance GHC.Base.Functor Data.Aeson.Possible.Possible
- Data.Aeson.Possible: instance GHC.Generics.Generic (Data.Aeson.Possible.Possible a)
- Data.Aeson.Possible: instance GHC.Show.Show a => GHC.Show.Show (Data.Aeson.Possible.Possible a)
+ Data.Aeson.Possible: fromMaybe :: Possible a -> Maybe a -> Possible a
+ Data.Aeson.Possible: fromMaybeMissing :: Maybe a -> Possible a
+ Data.Aeson.Possible: fromMaybeNull :: Maybe a -> Possible a
+ Data.Aeson.Possible: instance GHC.Internal.Base.Alternative Data.Aeson.Possible.Possible
+ Data.Aeson.Possible: instance GHC.Internal.Base.Applicative Data.Aeson.Possible.Possible
+ Data.Aeson.Possible: instance GHC.Internal.Base.Functor Data.Aeson.Possible.Possible
+ Data.Aeson.Possible: instance GHC.Internal.Generics.Generic (Data.Aeson.Possible.Possible a)
+ Data.Aeson.Possible: instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Aeson.Possible.Possible a)
+ Data.Aeson.Possible: toMaybeMaybe :: Possible a -> Maybe (Maybe a)

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for aeson-possible +## 0.1.1.0 -- 2025-12-04++* Add more utility functions for conversions+* Tests and documentation improvements+* Expand GHC versions tested against+ ## 0.1.0.1 -- 2024-06-27  * Fix errors in documentation on use of Aeson `Options`
aeson-possible.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               aeson-possible-version:            0.1.0.1+version:            0.1.1.0 synopsis:           Possible values for aeson description:        Three-valued possible types for use with aeson.                     Useful for use in PATCH endpoints.@@ -16,6 +16,8 @@   GHC == 9.4    || == 9.6    || == 9.8+   || == 9.10+   || == 9.12  common extensions     default-extensions:
src/Data/Aeson/Possible.hs view
@@ -1,5 +1,5 @@ {- |-Three-valued possible types for use with `aeson`.+Three-valued possible types for use with [aeson](https://hackage.haskell.org/package/aeson)  Useful for use in PATCH endpoints: use in records which have 'ToJSON' and 'FromJSON' instances.@@ -22,8 +22,22 @@ -} module Data.Aeson.Possible (     Possible (..),-    toMaybe,++    -- * Utility functions++    -- ** Equivalent expressiveness++    -- | Keep the same level of expressiveness using nested @Maybe@s+    toMaybeMaybe,     fromMaybeMaybe,++    -- ** With different expressiveness++    -- | Helpers that either inject extra meaning ('fromMaybe'), or lose it ('toMaybe').+    toMaybe,+    fromMaybe,+    fromMaybeNull,+    fromMaybeMissing, ) where  import Control.Applicative@@ -58,12 +72,12 @@     Missing <|> r = r     l@(HaveData _) <|> _ = l -{- | Uses 'toMaybe' to implement `toJSON` and `toEncoding`, and `aeson`'s+{- | Uses 'toMaybe' to implement @toJSON@ and @toEncoding@, and @aeson@'s 'omitField' to specify when the field should be left out.  /Note/ that unless the 'Possible' value is encoded as an object field it-will be `null` even when you have a 'Missing' value.-_e.g._ `[Missing, HaveNull, HaveData 42]` will be encoded as `[null,null,42]`+will be @null@ even when you have a 'Missing' value.+_e.g._ @[Missing, HaveNull, HaveData 42]@ will be encoded as @[null,null,42]@ -} instance (ToJSON a) => ToJSON (Possible a) where     toJSON = toJSON . toMaybe@@ -72,18 +86,41 @@     omitField HaveNull = False     omitField (HaveData _) = False --- | Uses `omittedField` to default to 'Missing'+-- | Uses @omittedField@ to default to 'Missing' instance (FromJSON a) => FromJSON (Possible a) where     parseJSON Null = pure HaveNull     parseJSON v = fmap pure . parseJSON $ v     omittedField = Just Missing -toMaybe :: Possible a -> Maybe a-toMaybe Missing = Nothing-toMaybe HaveNull = Nothing-toMaybe (HaveData a) = Just a+toMaybeMaybe :: Possible a -> Maybe (Maybe a)+toMaybeMaybe Missing = Nothing+toMaybeMaybe HaveNull = Just Nothing+toMaybeMaybe (HaveData a) = Just (Just a)  fromMaybeMaybe :: Maybe (Maybe a) -> Possible a fromMaybeMaybe Nothing = Missing fromMaybeMaybe (Just Nothing) = HaveNull fromMaybeMaybe (Just (Just a)) = HaveData a++toMaybe :: Possible a -> Maybe a+toMaybe Missing = Nothing+toMaybe HaveNull = Nothing+toMaybe (HaveData a) = Just a++{- | Analogous to @Maybe@'s @fromMaybe@: first parameter is a default to use, for example:++> fromMaybe HaveNull p++/Note:/ You can use @fromMaybe (HaveData a)@, even though that is not the intended usage.+-}+fromMaybe :: Possible a -> Maybe a -> Possible a+fromMaybe def Nothing = def+fromMaybe _ (Just a) = HaveData a++-- | @Nothing@ becomes 'HaveNull'+fromMaybeNull :: Maybe a -> Possible a+fromMaybeNull = fromMaybe HaveNull++-- | @Nothing@ becomes 'Missing'+fromMaybeMissing :: Maybe a -> Possible a+fromMaybeMissing = fromMaybe Missing
test/Main.hs view
@@ -18,7 +18,7 @@ main = defaultMain tests  tests :: TestTree-tests = testGroup "Tests" [laws, unitTests]+tests = testGroup "Tests" [laws, unitTests, helperTests]  newtype A_Possible a = A_Possible {unwrap :: Possible a}     deriving stock (Show, Generic, Functor)@@ -109,4 +109,16 @@             , testCase "Decode value" $                 eitherDecode "true" @?= Right (HaveData True)             ]+        ]++helperTests :: TestTree+helperTests =+    testGroup+        "Test helpers"+        [ QC.testProperty "Maybe Maybe two-way" $ \(p' :: A_Possible Bool) ->+            let p = unwrap p'+             in p === fromMaybeMaybe (toMaybeMaybe p)+        , QC.testProperty "Single Maybe two-way with default" $ \(p' :: A_Possible Bool) ->+            let p = unwrap p'+             in p === fromMaybe p (toMaybe p)         ]