keiki-codec-json 0.4.0.0 → 0.5.0.0
raw patch · 3 files changed
+45/−7 lines, 3 filesdep ~keikidep ~keiki-codec-jsonPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: keiki, keiki-codec-json
API changes (from Hackage documentation)
Files
- CHANGELOG.md +10/−0
- keiki-codec-json.cabal +6/−6
- test/Keiki/Codec/JSON/PropSpec.hs +29/−1
CHANGELOG.md view
@@ -9,6 +9,16 @@ ## [Unreleased] +## [0.5.0.0] — 2026-07-31++### Added++- `Natural` registers are supported on the wire alongside `keiki`'s new+ `Natural` symbolic domain. A `Natural` slot round-trips as a JSON number,+ and decoding rejects negative and fractional numbers rather than truncating+ them. The property suite pins both directions.++ ## [0.4.0.0] — 2026-07-28 ### Changed
keiki-codec-json.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: keiki-codec-json-version: 0.4.0.0+version: 0.5.0.0 synopsis: Optional JSON codec for keiki's RegFile. description: Sibling package to keiki providing a JSON encoder, decoder, and@@ -81,7 +81,7 @@ , aeson ^>=2.2 , base ^>=4.21 , containers ^>=0.7- , keiki ^>=0.4+ , keiki ^>=0.5 , scientific ^>=0.3 , template-haskell ^>=2.23 , text ^>=2.1@@ -96,8 +96,8 @@ , base ^>=4.21 , bytestring ^>=0.12 , deepseq ^>=1.5- , keiki ^>=0.4- , keiki-codec-json ^>=0.4+ , keiki ^>=0.5+ , keiki-codec-json ^>=0.5 , tasty-bench ^>=0.4 || ^>=0.5 , text ^>=2.1 @@ -124,8 +124,8 @@ , bytestring ^>=0.12 , containers ^>=0.7 , hspec ^>=2.11- , keiki ^>=0.4- , keiki-codec-json ^>=0.4+ , keiki ^>=0.5+ , keiki-codec-json ^>=0.5 , QuickCheck ^>=2.15 , quickcheck-instances ^>=0.3 , text ^>=2.1
test/Keiki/Codec/JSON/PropSpec.hs view
@@ -22,7 +22,8 @@ ) import Keiki.Core (RegFile) import Keiki.Core qualified as Core-import Test.Hspec (Spec, describe, it, shouldBe)+import Numeric.Natural (Natural)+import Test.Hspec (Spec, describe, expectationFailure, it, shouldBe) import Test.QuickCheck (Property, forAllShow, (===)) -- | RegFile rs has no Show instance (the slot list is heterogeneous);@@ -35,6 +36,7 @@ describe "ExemplarSlots" (codecProps @ExemplarSlots) describe "MaybeSlots" (codecProps @MaybeSlots) nestedMaybeSpec+ naturalSpec codecProps :: forall rs.@@ -125,3 +127,29 @@ case regFileFromJSON @NestedMaybeSlots (regFileToJSON rf) of Left message -> error ("nested Maybe decode failed: " <> message) Right (Core.RCons _ actual Core.RNil) -> actual `shouldBe` expected++type NaturalSlots = '[ '("revision", Natural)]++naturalSpec :: Spec+naturalSpec = describe "Natural wire semantics" $ do+ it "round-trips zero and a positive revision as JSON numbers" $ do+ assertNaturalDecode 0+ assertNaturalDecode 42++ it "rejects negative and fractional JSON numbers" $ do+ assertNaturalRejected (Aeson.object ["revision" Aeson..= (-1 :: Int)])+ assertNaturalRejected (Aeson.object ["revision" Aeson..= (1.5 :: Double)])++assertNaturalDecode :: Natural -> IO ()+assertNaturalDecode expected =+ case regFileFromJSON @NaturalSlots (regFileToJSON naturalRegister) of+ Left message -> error ("Natural decode failed: " <> message)+ Right (Core.RCons _ actual Core.RNil) -> actual `shouldBe` expected+ where+ naturalRegister = Core.RCons (Proxy @"revision") expected Core.RNil++assertNaturalRejected :: Aeson.Value -> IO ()+assertNaturalRejected value =+ case regFileFromJSON @NaturalSlots value of+ Left _ -> pure ()+ Right _ -> expectationFailure "expected an invalid Natural JSON value to be rejected"