packages feed

aeson-deriving 0.1.0.0 → 0.1.1

raw patch · 8 files changed

+75/−6 lines, 8 filesdep +regex-tdfaPVP ok

version bump matches the API change (PVP)

Dependencies added: regex-tdfa

API changes (from Hackage documentation)

+ Data.Aeson.Deriving: data TextWithPattern (regex :: Symbol)
+ Data.Aeson.Deriving.Generic: data FirstChar a
+ Data.Aeson.Deriving.Internal.Generic: data FirstChar a
+ Data.Aeson.Deriving.Internal.Generic: instance forall k (a :: k). Data.Aeson.Deriving.Internal.Generic.StringFunction a => Data.Aeson.Deriving.Internal.Generic.StringFunction (Data.Aeson.Deriving.Internal.Generic.FirstChar a)

Files

ChangeLog.md view
@@ -1,7 +1,11 @@ # Changelog for aeson-deriving -## Unreleased changes+# Revision history for servant-openapi - * A newtype for encoding Aeson's generic Options type- * A newtype for sums of records- * A newtype for nesting the encoding under a single field+### 0.1.1++* Added newtype for Text validated against a regex pattern [PR 2](https://github.com/fieldstrength/aeson-deriving/pull/2)++## 0.1.0++* First version. Released on an unsuspecting world.
aeson-deriving.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: bd8e2b4289bac4670675ad3e5d5307767ea3ad1d4a053a709b95767944b84df0+-- hash: 10c4d376657004b7575f0a910fbcb4dd80c3a284e99343ca3f3e962eeba7cd0e  name:           aeson-deriving-version:        0.1.0.0+version:        0.1.1 synopsis:       data types for compositional, type-directed serialization description:    Please see the README on GitHub at <https://github.com/fieldstrength/aeson-deriving#readme> category:       Serialization@@ -39,6 +39,8 @@       Data.Aeson.Deriving.Utils       Data.Aeson.Deriving.WithConstantFields   other-modules:+      Data.Aeson.Deriving.Text+      Data.Aeson.Deriving.Text.Unsafe       Paths_aeson_deriving   hs-source-dirs:       src@@ -47,6 +49,7 @@   build-depends:       aeson >=1.2 && <1.5     , base >=4.7 && <5+    , regex-tdfa     , text     , unordered-containers   default-language: Haskell2010@@ -65,6 +68,7 @@     , aeson-deriving     , base >=4.7 && <5     , hedgehog+    , regex-tdfa     , text     , unordered-containers   default-language: Haskell2010
src/Data/Aeson/Deriving.hs view
@@ -4,4 +4,5 @@ import           Data.Aeson.Deriving.Known              as AllExports import           Data.Aeson.Deriving.ModifyField        as AllExports import           Data.Aeson.Deriving.SingleFieldObject  as AllExports+import           Data.Aeson.Deriving.Text               as AllExports import           Data.Aeson.Deriving.WithConstantFields as AllExports
src/Data/Aeson/Deriving/Generic.hs view
@@ -31,6 +31,7 @@   , SnakeCase   , Uppercase   , Lowercase+  , FirstChar   , DropLowercasePrefix   , DropPrefix   , DropSuffix
src/Data/Aeson/Deriving/Internal/Generic.hs view
@@ -304,6 +304,7 @@ data SnakeCase data Uppercase data Lowercase+data FirstChar a -- | Applies 'dropLowercasePrefix', dropping until the first uppercase character. data DropLowercasePrefix data DropPrefix (str :: Symbol)@@ -328,6 +329,11 @@   stringFunction Proxy x     | x == symbolVal (Proxy @a) = symbolVal (Proxy @b)     | otherwise = x++instance StringFunction a => StringFunction (FirstChar a) where+  stringFunction Proxy = \case+    [] -> []+    c:cs -> stringFunction (Proxy @a) [c] ++ cs  ------------------------------------------------------------------------------------------ -- Sum type encodings
+ src/Data/Aeson/Deriving/Text.hs view
@@ -0,0 +1,5 @@+module Data.Aeson.Deriving.Text+  ( TextWithPattern+  ) where++import Data.Aeson.Deriving.Text.Unsafe (TextWithPattern)
+ src/Data/Aeson/Deriving/Text/Unsafe.hs view
@@ -0,0 +1,17 @@+module Data.Aeson.Deriving.Text.Unsafe where++import           Control.Monad   (unless)+import           Data.Aeson+import           Data.Proxy+import           Data.Text       (Text, unpack)+import           Text.Regex.TDFA ((=~))+import           GHC.TypeLits    (KnownSymbol, Symbol, symbolVal)++newtype TextWithPattern (regex :: Symbol) = TextWithPattern Text+  deriving newtype (ToJSON)++instance KnownSymbol regex => FromJSON (TextWithPattern regex) where+  parseJSON = withText "Text" $ \s ->+    TextWithPattern s <$ unless (unpack s =~ (symbolVal $ Proxy @regex)) (fail errorMsg)+    where+      errorMsg = "must match regex " <> (symbolVal $ Proxy @regex)
test/Main.hs view
@@ -8,6 +8,9 @@  import Data.Aeson import Data.Aeson.Deriving+import Data.Foldable (for_)+import Data.Aeson.Deriving.Text.Unsafe+import Data.Text import GHC.Generics import Hedgehog import Hedgehog.Main (defaultMain)@@ -186,3 +189,31 @@   tripping (Reserved "Sen" 9 'x') encode decode   Just (Reserved "Sen" 9 'x') ===     decode "{\"control\":\"x\",\"module\":9,\"type\":\"Sen\"}"++newtype DashSeparatedWords = DashSeparatedWords Text+  deriving stock (Generic, Show, Eq)+  deriving (FromJSON, ToJSON) via TextWithPattern "^([A-Za-z]+-)*[A-Za-z]+$"++prop_accepts_matches :: Property+prop_accepts_matches = once . property $ do+  tripping (DashSeparatedWords "foo-bar-baz") encode decode+  Just (DashSeparatedWords "foo-bar-baz") === decode "\"foo-bar-baz\""++prop_rejects_non_matches :: Property+prop_rejects_non_matches = once . property $ do+  Left "Error in $: must match regex ^([A-Za-z]+-)*[A-Za-z]+$" === eitherDecode @DashSeparatedWords "\"foo.42\""+++data Heavy = BlackHole | NeutronStar+ deriving stock (Generic, Show, Eq, Ord, Bounded, Enum)+ deriving (FromJSON, ToJSON) via GenericEncoded '[ConstructorTagModifier := FirstChar Lowercase] Heavy++prop_first_char_modifier_encodes_as_expected :: Property+prop_first_char_modifier_encodes_as_expected = once . property $ do+  encode BlackHole === "\"blackHole\""+  encode NeutronStar === "\"neutronStar\""++prop_first_char_modifier_decodes_as_expected :: Property+prop_first_char_modifier_decodes_as_expected = once . property $ do+  for_ [BlackHole ..] $ \x ->+    tripping x encode decode