Skip to content

Commit 3c5c44b

Browse files
committed
feat: encoder implementation that is not dependent on class -> move implementation to Implementation module
1 parent 8f47b19 commit 3c5c44b

File tree

6 files changed

+167
-64
lines changed

6 files changed

+167
-64
lines changed

src/Data/Argonaut/Decode/Class.purs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ module Data.Argonaut.Decode.Class where
22

33
import Prelude (class Ord, Unit, Void, bind, ($), (<<<), (<>))
44

5-
import Data.Argonaut.Core (Json, fromString, toObject)
5+
import Data.Argonaut.Core (Json, toObject)
66
import Data.Array.NonEmpty (NonEmptyArray)
7-
import Data.Bifunctor (lmap)
87
import Data.Either (Either(..))
98
import Data.Identity (Identity)
109
import Data.List (List)

src/Data/Argonaut/Decode/Implementation.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Data.Bifunctor (lmap, rmap)
1010
import Data.Either (Either(..), note)
1111
import Data.Identity (Identity(..))
1212
import Data.Int (fromNumber)
13-
import Data.List (List(..), (:), fromFoldable)
13+
import Data.List (List, fromFoldable)
1414
import Data.List as L
1515
import Data.List.NonEmpty (NonEmptyList)
1616
import Data.List.NonEmpty as NEL

src/Data/Argonaut/Encode.purs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
module Data.Argonaut.Encode
22
( module Data.Argonaut.Encode.Class
33
, module Data.Argonaut.Encode.Combinators
4+
, module Data.Argonaut.Encode.Implementation
45
) where
56

67
import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson)
7-
import Data.Argonaut.Encode.Combinators
8+
import Data.Argonaut.Encode.Combinators
89
( assoc
910
, assocOptional
1011
, extend
@@ -14,3 +15,4 @@ import Data.Argonaut.Encode.Combinators
1415
, (~>)
1516
, (~>?)
1617
)
18+
import Data.Argonaut.Encode.Implementation (Encoder)

src/Data/Argonaut/Encode/Class.purs

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,95 @@
11
module Data.Argonaut.Encode.Class where
22

3-
import Prelude
3+
import Prelude (class Ord, Unit, Void, ($))
44

5-
import Data.Argonaut.Core (Json, fromArray, fromBoolean, fromNumber, fromObject, fromString, jsonNull)
6-
import Data.Array as Arr
5+
import Data.Argonaut.Core (Json, fromObject)
76
import Data.Array.NonEmpty (NonEmptyArray)
8-
import Data.Array.NonEmpty as NEA
9-
import Data.Either (Either, either)
10-
import Data.Identity (Identity(..))
11-
import Data.Int (toNumber)
12-
import Data.List (List(..), (:), toUnfoldable)
13-
import Data.List as L
14-
import Data.List.NonEmpty as NEL
7+
import Data.Either (Either)
8+
import Data.Identity (Identity)
9+
import Data.List (List)
1510
import Data.List.Types (NonEmptyList)
1611
import Data.Map as M
17-
import Data.Maybe (Maybe(..))
18-
import Data.NonEmpty (NonEmpty(..))
12+
import Data.Maybe (Maybe)
13+
import Data.NonEmpty (NonEmpty)
1914
import Data.Set as S
2015
import Data.String (CodePoint)
21-
import Data.String.CodePoints as CP
22-
import Data.String.CodeUnits as CU
2316
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
24-
import Data.Tuple (Tuple(..))
17+
import Data.Tuple (Tuple)
2518
import Foreign.Object as FO
2619
import Prim.Row as Row
2720
import Prim.RowList as RL
2821
import Record as Record
2922
import Type.Data.RowList (RLProxy(..))
23+
import Data.Argonaut.Encode.Implementation
3024

3125
class EncodeJson a where
32-
encodeJson :: a -> Json
26+
encodeJson :: Encoder a
3327

3428
instance encodeIdentity :: EncodeJson a => EncodeJson (Identity a) where
35-
encodeJson (Identity a) = encodeJson a
29+
encodeJson = encodeIdentity encodeJson
3630

3731
instance encodeJsonMaybe :: EncodeJson a => EncodeJson (Maybe a) where
38-
encodeJson = case _ of
39-
Nothing -> jsonNull
40-
Just a -> encodeJson a
32+
encodeJson = encodeJsonMaybe encodeJson
4133

4234
instance encodeJsonTuple :: (EncodeJson a, EncodeJson b) => EncodeJson (Tuple a b) where
43-
encodeJson (Tuple a b) = encodeJson [encodeJson a, encodeJson b]
35+
encodeJson = encodeJsonTuple encodeJson encodeJson
4436

4537
instance encodeJsonEither :: (EncodeJson a, EncodeJson b) => EncodeJson (Either a b) where
46-
encodeJson = either (obj "Left") (obj "Right")
47-
where
48-
obj :: forall c. EncodeJson c => String -> c -> Json
49-
obj tag x =
50-
fromObject
51-
$ FO.fromFoldable
52-
$ Tuple "tag" (fromString tag) : Tuple "value" (encodeJson x) : Nil
38+
encodeJson = encodeJsonEither encodeJson encodeJson
5339

5440
instance encodeJsonUnit :: EncodeJson Unit where
55-
encodeJson = const jsonNull
41+
encodeJson = encodeJsonUnit
5642

5743
instance encodeJsonJBoolean :: EncodeJson Boolean where
58-
encodeJson = fromBoolean
44+
encodeJson = encodeJsonJBoolean
5945

6046
instance encodeJsonJNumber :: EncodeJson Number where
61-
encodeJson = fromNumber
47+
encodeJson = encodeJsonJNumber
6248

6349
instance encodeJsonInt :: EncodeJson Int where
64-
encodeJson = fromNumber <<< toNumber
50+
encodeJson = encodeJsonInt
6551

6652
instance encodeJsonJString :: EncodeJson String where
67-
encodeJson = fromString
53+
encodeJson = encodeJsonJString
6854

6955
instance encodeJsonJson :: EncodeJson Json where
70-
encodeJson = identity
56+
encodeJson = encodeJsonJson
7157

7258
instance encodeJsonCodePoint :: EncodeJson CodePoint where
73-
encodeJson = encodeJson <<< CP.singleton
59+
encodeJson = encodeJsonCodePoint
7460

7561
instance encodeJsonNonEmpty_Array :: (EncodeJson a) => EncodeJson (NonEmpty Array a) where
76-
encodeJson (NonEmpty h t) = encodeJson (Arr.cons h t)
62+
encodeJson = encodeJsonNonEmpty_Array encodeJson
7763

7864
instance encodeJsonNonEmptyArray :: (EncodeJson a) => EncodeJson (NonEmptyArray a) where
79-
encodeJson = encodeJson <<< NEA.toArray
65+
encodeJson = encodeJsonNonEmptyArray encodeJson
8066

8167
instance encodeJsonNonEmpty_List :: (EncodeJson a) => EncodeJson (NonEmpty List a) where
82-
encodeJson (NonEmpty h t) = encodeJson (L.insertAt 0 h t)
68+
encodeJson = encodeJsonNonEmpty_List encodeJson
8369

8470
instance encodeJsonNonEmptyList :: (EncodeJson a) => EncodeJson (NonEmptyList a) where
85-
encodeJson = encodeJson <<< NEL.toList
71+
encodeJson = encodeJsonNonEmptyList encodeJson
8672

8773
instance encodeJsonChar :: EncodeJson Char where
88-
encodeJson = encodeJson <<< CU.singleton
74+
encodeJson = encodeJsonChar
8975

9076
instance encodeJsonArray :: EncodeJson a => EncodeJson (Array a) where
91-
encodeJson = fromArray <<< map encodeJson
77+
encodeJson = encodeJsonArray encodeJson
9278

9379
instance encodeJsonList :: EncodeJson a => EncodeJson (List a) where
94-
encodeJson = fromArray <<< map encodeJson <<< toUnfoldable
80+
encodeJson = encodeJsonList encodeJson
9581

9682
instance encodeForeignObject :: EncodeJson a => EncodeJson (FO.Object a) where
97-
encodeJson = fromObject <<< map encodeJson
83+
encodeJson = encodeForeignObject encodeJson
9884

9985
instance encodeSet :: (Ord a, EncodeJson a) => EncodeJson (S.Set a) where
100-
encodeJson = encodeJson <<< (S.toUnfoldable :: S.Set a -> List a)
86+
encodeJson = encodeSet encodeJson
10187

10288
instance encodeMap :: (Ord a, EncodeJson a, EncodeJson b) => EncodeJson (M.Map a b) where
103-
encodeJson = encodeJson <<< (M.toUnfoldable :: M.Map a b -> List (Tuple a b))
89+
encodeJson = encodeMap encodeJson encodeJson
10490

10591
instance encodeVoid :: EncodeJson Void where
106-
encodeJson = absurd
92+
encodeJson = encodeVoid
10793

10894
instance encodeRecord
10995
:: ( GEncodeJson row list

src/Data/Argonaut/Encode/Combinators.purs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,19 @@
99
-- | ```
1010
module Data.Argonaut.Encode.Combinators where
1111

12-
import Prelude
1312

14-
import Data.Argonaut.Core (Json, caseJsonObject, fromObject, jsonSingletonObject)
13+
import Data.Argonaut.Core (Json)
1514
import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson)
16-
import Data.Maybe (Maybe(..))
17-
import Data.Tuple (Tuple(..))
18-
import Foreign.Object as FO
15+
import Data.Maybe (Maybe)
16+
import Data.Tuple (Tuple)
17+
import Data.Argonaut.Encode.Implementation as Implementation
1918

2019
-- | Creates a `Tuple String Json` entry, representing a key/value pair for an object.
2120
infix 7 assoc as :=
2221

2322
-- | The named implementation of the `(:=)` operator.
2423
assoc :: forall a. EncodeJson a => String -> a -> Tuple String Json
25-
assoc k = Tuple k <<< encodeJson
24+
assoc = Implementation.assoc encodeJson
2625

2726
-- | Creates an optional `Tuple String Json` entry, representing an optional key/value pair for an object.
2827
infix 7 assocOptional as :=?
@@ -34,23 +33,18 @@ assocOptional
3433
=> String
3534
-> Maybe a
3635
-> Maybe (Tuple String Json)
37-
assocOptional k = (<$>) (((:=) k) <<< encodeJson)
36+
assocOptional = Implementation.assocOptional encodeJson
3837

3938
-- | Extends a Json object with a `Tuple String Json` property.
4039
infixr 6 extend as ~>
4140

4241
-- | The named implementation of the `(~>)` operator.
4342
extend :: forall a. EncodeJson a => Tuple String Json -> a -> Json
44-
extend (Tuple k v) =
45-
caseJsonObject
46-
(jsonSingletonObject k v)
47-
(FO.insert k v >>> fromObject)
48-
<<< encodeJson
43+
extend = Implementation.extend encodeJson
4944

5045
-- | Optionally extends a Json object with an optional `Tuple String Json` property.
5146
infixr 6 extendOptional as ~>?
5247

5348
-- | The named implementation of the `(~>?)` operator.
5449
extendOptional :: forall a. EncodeJson a => Maybe (Tuple String Json) -> a -> Json
55-
extendOptional (Just kv) = (~>) kv
56-
extendOptional Nothing = encodeJson
50+
extendOptional = Implementation.extendOptional encodeJson
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
module Data.Argonaut.Encode.Implementation where
2+
3+
import Prelude
4+
5+
import Data.Argonaut.Core (Json, fromArray, fromBoolean, fromNumber, fromObject, fromString, jsonNull, caseJsonObject, jsonSingletonObject)
6+
import Data.Array as Arr
7+
import Data.Array.NonEmpty (NonEmptyArray)
8+
import Data.Array.NonEmpty as NEA
9+
import Data.Either (Either, either)
10+
import Data.Identity (Identity(..))
11+
import Data.Int (toNumber)
12+
import Data.List (List(..), (:), toUnfoldable)
13+
import Data.List.NonEmpty as NEL
14+
import Data.List.Types (NonEmptyList)
15+
import Data.Map as M
16+
import Data.Maybe (Maybe(..))
17+
import Data.NonEmpty (NonEmpty(..))
18+
import Data.Set as S
19+
import Data.String (CodePoint)
20+
import Data.String.CodePoints as CP
21+
import Data.String.CodeUnits as CU
22+
import Data.Tuple (Tuple(..))
23+
import Foreign.Object as FO
24+
25+
type Encoder a = a -> Json
26+
27+
encodeIdentity :: forall a . Encoder a -> Encoder (Identity a)
28+
encodeIdentity encoder (Identity a) = encoder a
29+
30+
encodeJsonMaybe :: forall a . Encoder a -> Encoder (Maybe a)
31+
encodeJsonMaybe encoder = case _ of
32+
Nothing -> jsonNull
33+
Just a -> encoder a
34+
35+
encodeJsonTuple :: forall a b . Encoder a -> Encoder b -> Encoder (Tuple a b)
36+
encodeJsonTuple encoderA encoderB (Tuple a b) = fromArray [encoderA a, encoderB b]
37+
38+
encodeJsonEither :: forall a b . Encoder a -> Encoder b -> Encoder (Either a b)
39+
encodeJsonEither encoderA encoderB = either (obj encoderA "Left") (obj encoderB "Right")
40+
where
41+
obj :: forall c. Encoder c -> String -> c -> Json
42+
obj encoder tag x =
43+
fromObject
44+
$ FO.fromFoldable
45+
$ Tuple "tag" (fromString tag) : Tuple "value" (encoder x) : Nil
46+
47+
encodeJsonUnit :: Encoder Unit
48+
encodeJsonUnit = const jsonNull
49+
50+
encodeJsonJBoolean :: Encoder Boolean
51+
encodeJsonJBoolean = fromBoolean
52+
53+
encodeJsonJNumber :: Encoder Number
54+
encodeJsonJNumber = fromNumber
55+
56+
encodeJsonInt :: Encoder Int
57+
encodeJsonInt = fromNumber <<< toNumber
58+
59+
encodeJsonJString :: Encoder String
60+
encodeJsonJString = fromString
61+
62+
encodeJsonJson :: Encoder Json
63+
encodeJsonJson = identity
64+
65+
encodeJsonCodePoint :: Encoder CodePoint
66+
encodeJsonCodePoint = encodeJsonJString <<< CP.singleton
67+
68+
encodeJsonNonEmpty_Array :: forall a . (Encoder a) -> Encoder (NonEmpty Array a)
69+
encodeJsonNonEmpty_Array encoder (NonEmpty h t) = encodeJsonArray encoder (Arr.cons h t)
70+
71+
encodeJsonNonEmptyArray :: forall a . (Encoder a) -> Encoder (NonEmptyArray a)
72+
encodeJsonNonEmptyArray encoder = encodeJsonArray encoder <<< NEA.toArray
73+
74+
encodeJsonNonEmpty_List :: forall a . (Encoder a) -> Encoder (NonEmpty List a)
75+
encodeJsonNonEmpty_List encoder (NonEmpty h t) = encodeJsonList encoder (h : t)
76+
77+
encodeJsonNonEmptyList :: forall a . (Encoder a) -> Encoder (NonEmptyList a)
78+
encodeJsonNonEmptyList encoder = encodeJsonList encoder <<< NEL.toList
79+
80+
encodeJsonChar :: Encoder Char
81+
encodeJsonChar = encodeJsonJString <<< CU.singleton
82+
83+
encodeJsonArray :: forall a . Encoder a -> Encoder (Array a)
84+
encodeJsonArray encoder = fromArray <<< map encoder
85+
86+
encodeJsonList :: forall a . Encoder a -> Encoder (List a)
87+
encodeJsonList encoder = fromArray <<< map encoder <<< toUnfoldable
88+
89+
encodeForeignObject :: forall a . Encoder a -> Encoder (FO.Object a)
90+
encodeForeignObject encoder = fromObject <<< map encoder
91+
92+
encodeSet :: forall a . (Ord a) => Encoder a -> Encoder (S.Set a)
93+
encodeSet encoder = encodeJsonList encoder <<< (S.toUnfoldable :: S.Set a -> List a)
94+
95+
encodeMap :: forall a b . (Ord a) => Encoder a -> Encoder b -> Encoder (M.Map a b)
96+
encodeMap encoderA encoderB = encodeJsonList (encodeJsonTuple encoderA encoderB) <<< (M.toUnfoldable :: M.Map a b -> List (Tuple a b))
97+
98+
encodeVoid :: Encoder Void
99+
encodeVoid = absurd
100+
101+
assoc :: forall a. Encoder a -> String -> a -> Tuple String Json
102+
assoc encoder k = Tuple k <<< encoder
103+
104+
assocOptional
105+
:: forall a
106+
. Encoder a
107+
-> String
108+
-> Maybe a
109+
-> Maybe (Tuple String Json)
110+
assocOptional encoder k = (<$>) (Tuple k <<< encoder)
111+
112+
extend :: forall a. Encoder a -> Tuple String Json -> a -> Json
113+
extend encoder (Tuple k v) =
114+
caseJsonObject
115+
(jsonSingletonObject k v)
116+
(FO.insert k v >>> fromObject)
117+
<<< encoder
118+
119+
-- | The named implementation of the `(~>?)` operator.
120+
extendOptional :: forall a. Encoder a -> Maybe (Tuple String Json) -> a -> Json
121+
extendOptional encoder (Just kv) = extend encoder kv
122+
extendOptional encoder Nothing = encoder

0 commit comments

Comments
 (0)