Skip to content

Commit f8334e9

Browse files
Merge pull request #26 from dgendill/master
Instances for NonEmpty Array and NonEmpty List
2 parents 82efbd5 + b55a033 commit f8334e9

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

bower.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
"purescript-maybe": "^4.0.0",
2828
"purescript-ordered-collections": "^1.0.0",
2929
"purescript-foreign-object": "^1.0.0",
30-
"purescript-record": "^1.0.0"
30+
"purescript-record": "^1.0.0",
31+
"purescript-nonempty": "^5.0.0",
32+
"purescript-arrays": "^5.1.0"
3133
},
3234
"devDependencies": {
3335
"purescript-test-unit": "^14.0.0"

src/Data/Argonaut/Decode/Class.purs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ module Data.Argonaut.Decode.Class where
22

33
import Prelude
44

5+
import Control.Alternative (class Plus)
56
import Data.Argonaut.Core (Json, isNull, caseJsonNull, caseJsonBoolean, caseJsonNumber, caseJsonString, toArray, toObject, toString, stringify)
6-
import Data.Bifunctor (lmap)
7-
import Data.Either (Either(..))
7+
import Data.Array as Arr
8+
import Data.Bifunctor (lmap, rmap)
9+
import Data.Either (Either(..), note)
810
import Data.Int (fromNumber)
911
import Data.List (List(..), (:), fromFoldable)
12+
import Data.List as L
1013
import Data.Map as M
1114
import Data.Maybe (maybe, Maybe(..))
15+
import Data.NonEmpty (NonEmpty, singleton, (:|))
1216
import Data.String (CodePoint, codePointAt)
1317
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
1418
import Data.Traversable (traverse)
@@ -66,6 +70,16 @@ instance decodeJsonString :: DecodeJson String where
6670
instance decodeJsonJson :: DecodeJson Json where
6771
decodeJson = Right
6872

73+
instance decodeJsonNonEmptyArray :: (DecodeJson a) => DecodeJson (NonEmpty Array a) where
74+
decodeJson
75+
= lmap ("Couldn't decode NonEmpty Array: " <> _)
76+
<<< (traverse decodeJson <=< (lmap ("JSON Array" <> _) <<< rmap (\x -> x.head :| x.tail) <<< note " is empty" <<< Arr.uncons) <=< decodeJArray)
77+
78+
instance decodeJsonNonEmptyList :: (DecodeJson a) => DecodeJson (NonEmpty List a) where
79+
decodeJson
80+
= lmap ("Couldn't decode NonEmpty List: " <> _)
81+
<<< (traverse decodeJson <=< (lmap ("JSON Array" <> _) <<< rmap (\x -> x.head :| x.tail) <<< note " is empty" <<< L.uncons) <=< map (map fromFoldable) decodeJArray)
82+
6983
instance decodeJsonChar :: DecodeJson CodePoint where
7084
decodeJson j =
7185
maybe (Left $ "Expected character but found: " <> stringify j) Right

src/Data/Argonaut/Encode/Class.purs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ module Data.Argonaut.Encode.Class where
33
import Prelude
44

55
import Data.Argonaut.Core (Json, fromArray, fromBoolean, fromNumber, fromObject, fromString, jsonNull)
6+
import Data.Array as Arr
67
import Data.Either (Either, either)
78
import Data.Int (toNumber)
89
import Data.List (List(..), (:), toUnfoldable)
10+
import Data.List as L
911
import Data.Map as M
1012
import Data.Maybe (Maybe(..))
13+
import Data.NonEmpty (NonEmpty(..))
1114
import Data.String (CodePoint)
1215
import Data.String.CodePoints as CP
1316
import Data.String.CodeUnits as CU
@@ -58,6 +61,12 @@ instance encodeJsonJson :: EncodeJson Json where
5861
instance encodeJsonCodePoint :: EncodeJson CodePoint where
5962
encodeJson = encodeJson <<< CP.singleton
6063

64+
instance encodeJsonNonEmptyArray :: (EncodeJson a) => EncodeJson (NonEmpty Array a) where
65+
encodeJson (NonEmpty h t) = encodeJson $ Arr.cons h t
66+
67+
instance encodeJsonNonEmptyList :: (EncodeJson a) => EncodeJson (NonEmpty List a) where
68+
encodeJson (NonEmpty h t) = encodeJson $ L.insertAt 0 h t
69+
6170
instance encodeJsonChar :: EncodeJson Char where
6271
encodeJson = encodeJson <<< CU.singleton
6372

test/Test/Main.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import Data.Argonaut.Parser (jsonParser)
1111
import Data.Bifunctor (rmap)
1212
import Data.Either (Either(..))
1313
import Data.Foldable (foldl)
14+
import Data.List (List)
1415
import Data.Maybe (Maybe(..), isJust, isNothing, maybe)
16+
import Data.NonEmpty (NonEmpty)
1517
import Data.String.Gen (genUnicodeString)
1618
import Data.Tuple (Tuple(..))
1719
import Effect (Effect)
@@ -28,6 +30,7 @@ import Test.Unit.QuickCheck (quickCheck)
2830
main :: Effect Unit
2931
main = runTest do
3032
suite "Either Check" eitherCheck
33+
suite "Encode/Decode NonEmpty Check" nonEmptyCheck
3134
suite "Encode/Decode Checks" encodeDecodeCheck
3235
suite "Encode/Decode Record Checks" encodeDecodeRecordCheck
3336
suite "Combinators Checks" combinatorsCheck
@@ -157,6 +160,25 @@ eitherCheck = do
157160
Left err ->
158161
false <?> err
159162

163+
nonEmptyCheck :: TestSuite
164+
nonEmptyCheck = do
165+
test "Test EncodeJson/DecodeJson on NonEmpty Array" do
166+
quickCheck \(x :: NonEmpty Array String) ->
167+
case decodeJson (encodeJson x) of
168+
Right decoded ->
169+
decoded == x
170+
<?> ("x = " <> show x <> ", decoded = " <> show decoded)
171+
Left err ->
172+
false <?> err
173+
test "Test EncodeJson/DecodeJson on NonEmpty List" do
174+
quickCheck \(x :: NonEmpty List String) ->
175+
case decodeJson (encodeJson x) of
176+
Right decoded ->
177+
decoded == x
178+
<?> ("x = " <> show x <> ", decoded = " <> show decoded)
179+
Left err ->
180+
false <?> err
181+
160182
errorMsgCheck :: TestSuite
161183
errorMsgCheck = do
162184
test "Test that decoding array fails with the proper message" do

0 commit comments

Comments
 (0)