Skip to content

Commit a045aea

Browse files
parsonsmattgaryb
authored andcommitted
Either decoding for IsForeign
1 parent 930419e commit a045aea

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

examples/Either.purs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module Examples.Either where
2+
3+
import Prelude
4+
import Control.Monad.Eff (Eff)
5+
import Data.Either (Either)
6+
7+
import Data.Foreign (F, parseJSON)
8+
import Data.Foreign.Class (class IsForeign, readEitherR, readProp)
9+
10+
import Control.Monad.Eff.Console (logShow, CONSOLE)
11+
12+
data Point = Point Number Number Number
13+
14+
instance showPoint :: Show Point where
15+
show (Point x y z) = "Point " <> show [x, y, z]
16+
17+
instance pointIsForeign :: IsForeign Point where
18+
read value = Point <$> readProp "x" value
19+
<*> readProp "y" value
20+
<*> readProp "z" value
21+
22+
type Response = Either (Array String) Point
23+
24+
main :: forall eff. Eff (console :: CONSOLE | eff) Unit
25+
main = do
26+
logShow do
27+
json <- parseJSON """{ "x":1, "y": 2, "z": 3}"""
28+
readEitherR json :: F Response
29+
30+
logShow do
31+
json <- parseJSON """["Invalid parse", "Not a valid y point"]"""
32+
readEitherR json :: F Response

src/Data/Foreign/Class.purs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ module Data.Foreign.Class
99
, class AsForeign
1010
, write
1111
, writeProp, (.=)
12+
, readEitherR
13+
, readEitherL
1214
) where
1315

1416
import Prelude
1517

18+
import Control.Alt ((<|>))
1619
import Data.Array (range, zipWith, length)
1720
import Data.Either (Either(..), either)
1821
import Data.Foreign (F, Foreign, ForeignError(..), Prop(..), parseJSON, readArray, readInt, readNumber, readBoolean, readChar, readString, toForeign)
@@ -120,3 +123,13 @@ infixl 8 writeProp as .=
120123

121124
writeProp :: forall a. AsForeign a => String -> a -> Prop
122125
writeProp k v = Prop { key: k, value: write v }
126+
127+
-- | Attempt to read a value that can be either one thing or another. This
128+
-- | implementation is right biased.
129+
readEitherR :: forall l r. (IsForeign l, IsForeign r) => Foreign -> F (Either l r)
130+
readEitherR value = Right <$> read value <|> Left <$> read value
131+
132+
-- | Attempt to read a value that can be either one thing or another. This
133+
-- | implementation is left biased.
134+
readEitherL :: forall l r. (IsForeign l, IsForeign r) => Foreign -> F (Either l r)
135+
readEitherL value = Left <$> read value <|> Right <$> read value

0 commit comments

Comments
 (0)