Skip to content

Commit 29e5255

Browse files
authored
Merge pull request #2 from dgendill/master
Update for 0.11
2 parents 72bfaf2 + fab2d38 commit 29e5255

File tree

6 files changed

+85
-85
lines changed

6 files changed

+85
-85
lines changed

README.md

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,32 @@ data GeoObject = GeoObject
1818

1919
## Decode YAML
2020

21-
Write `IsForeign` instances for your data structures.
21+
Write functions to read your data from foreign values.
2222

2323
```purescript
24-
instance pointIsForeign :: IsForeign Point where
25-
read value = do
26-
x <- readProp "X" value
27-
y <- readProp "Y" value
28-
return $ Point x y
29-
30-
instance mobilityIsForeign :: IsForeign Mobility where
31-
read value = do
32-
mob <- readString value
33-
case mob of
34-
"Fix" -> return Fix
35-
"Flex" -> return Flex
36-
_ -> Left $ JSONError "Mobility must be either Flex or Fix"
37-
38-
instance archiObjectIsForeign :: IsForeign GeoObject where
39-
read value = do
40-
name <- readProp "Name" value
41-
scale <- readProp "Scale" value
42-
points <- readProp "Points" value
43-
mobility <- readProp "Mobility" value
44-
coverage <- readProp "Coverage" value
45-
return $ GeoObject { name, scale, points, mobility, coverage }
24+
readPoint :: Foreign -> F Point
25+
readPoint value = do
26+
x <- readInt =<< readProp "X" value
27+
y <- readInt =<< readProp "Y" value
28+
pure $ Point x y
29+
30+
readMobility :: Foreign -> F Mobility
31+
readMobility value = do
32+
mob <- readString value
33+
case mob of
34+
"Fix" -> pure Fix
35+
"Flex" -> pure Flex
36+
_ -> fail $ JSONError "Mobility must be either Flex or Fix"
37+
38+
readGeoObject :: Foreign -> F GeoObject
39+
readGeoObject value = do
40+
name <- readString =<< readProp "Name" value
41+
scale <- readNumber =<< readProp "Scale" value
42+
points <- traverse readPoint =<< readArray =<< readProp "Points" value
43+
mobility <- readMobility =<< readProp "Mobility" value
44+
coverage <- readNumber =<< readProp "Coverage" value
45+
pure $ GeoObject { name, scale, points, mobility, coverage }
46+
4647
```
4748

4849
Read the YAML into your data structures.
@@ -74,7 +75,10 @@ yamlInput = """
7475
Coverage: 10
7576
"""
7677
77-
decoded = (readYAML yamlInput) :: F (Array GeoObject)
78+
let decoded =
79+
(parseYAML yamlInput) >>=
80+
readArray >>=
81+
traverse readGeoObject
7882
```
7983

8084
## Encode YAML

bower.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212
],
1313
"dependencies": {
1414
"js-yaml": "^3.4.6",
15-
"purescript-functions": "^2.0.0",
16-
"purescript-foreign": "^3.2.0",
17-
"purescript-foreign-generic": "^3.0.0",
18-
"purescript-unsafe-coerce": "^2.0.0"
15+
"purescript-functions": "^3.0.0",
16+
"purescript-foreign": "^4.0.0",
17+
"purescript-foreign-generic": "^4.1.0",
18+
"purescript-unsafe-coerce": "^3.0.0"
1919
},
2020
"devDependencies": {
21-
"purescript-console": "^2.0.0",
22-
"purescript-spec": "~0.12.1"
21+
"purescript-console": "^3.0.0",
22+
"purescript-spec": "^1.0.0"
2323
}
2424
}
25-

src/Data/YAML/Foreign/Decode.purs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
1-
module Data.YAML.Foreign.Decode (parseYAML, readYAML, readYAMLGeneric) where
1+
module Data.YAML.Foreign.Decode (parseYAML, readYAMLGeneric) where
22

33
import Data.Foreign (F, Foreign, ForeignError(..), fail)
4-
import Data.Foreign.Class (class IsForeign, read)
5-
import Data.Foreign.Generic (readGeneric)
6-
import Data.Foreign.Generic.Classes (class GenericDecode)
4+
import Data.Foreign.Generic.Class (class GenericDecode)
5+
import Data.Foreign.Generic (genericDecode)
76
import Data.Foreign.Generic.Types (Options)
87
import Data.Function.Uncurried (Fn3, runFn3)
98
import Data.Generic.Rep (class Generic)
10-
import Prelude (pure, (<<<), (>>=), (>=>))
9+
import Prelude ((>=>), (<<<), pure)
1110

1211
foreign import parseYAMLImpl :: forall r. Fn3 (String -> r) (Foreign -> r) String r
1312

1413
-- | Attempt to parse a YAML string, returning the result as foreign data.
1514
parseYAML :: String -> F Foreign
1615
parseYAML yaml = runFn3 parseYAMLImpl (fail <<< JSONError) pure yaml
1716

18-
-- | Attempt to parse a YAML string into the datastructure you want.
19-
readYAML :: forall a. (IsForeign a) => String -> F a
20-
readYAML yaml = parseYAML yaml >>= read
21-
2217
-- | Automatically generate a YAML parser for your data from a generic instance.
23-
readYAMLGeneric :: forall a rep. (Generic a rep, GenericDecode rep) => Options -> String -> F a
24-
readYAMLGeneric opts = parseYAML >=> readGeneric opts
25-
18+
readYAMLGeneric :: forall a rep. (Generic a rep) => (GenericDecode rep) => Options -> String -> F a
19+
readYAMLGeneric opts = parseYAML >=> genericDecode opts

src/Data/YAML/Foreign/Encode.purs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Data.YAML.Foreign.Encode where
22

33
import Data.Map as M
4-
import Data.Array (fromFoldable, toUnfoldable)
4+
import Data.Array (toUnfoldable)
55
import Data.Function.Uncurried (Fn4, runFn4)
66
import Data.List (List)
77
import Data.Maybe (Maybe, maybe)
@@ -11,7 +11,7 @@ import Unsafe.Coerce (unsafeCoerce)
1111

1212
type YObject = M.Map String YValue
1313
type YArray = Array YValue
14-
foreign import data YAML :: *
14+
foreign import data YAML :: Type
1515

1616
data YValue
1717
= YObject YObject
@@ -87,7 +87,7 @@ foreign import objToHash ::
8787
YAML
8888

8989
valueToYAML :: YValue -> YAML
90-
valueToYAML (YObject o) = runFn4 objToHash valueToYAML fst snd $ fromFoldable $ M.toList o
90+
valueToYAML (YObject o) = runFn4 objToHash valueToYAML fst snd $ M.toUnfoldable o
9191
valueToYAML (YArray a) = unsafeCoerce $ map valueToYAML a
9292
valueToYAML (YString s) = unsafeCoerce s
9393
valueToYAML (YNumber n) = unsafeCoerce n
@@ -99,4 +99,3 @@ foreign import toYAMLImpl :: YAML -> String
9999

100100
printYAML :: forall a. (ToYAML a) => a -> String
101101
printYAML = toYAMLImpl <<< valueToYAML <<< toYAML
102-

test/Instances.purs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
module Test.Instances where
22

3-
import Prelude (class Eq, class Show, bind, pure, ($))
4-
import Data.Foreign (ForeignError(..), fail, readString)
5-
import Data.Foreign.Class (class IsForeign, readProp)
3+
import Prelude (class Eq, class Show, bind, pure, ($), (=<<), (<$>), map, (<=<))
4+
import Data.Traversable (traverse)
5+
import Data.Foreign (readArray, readNumber, readString, readInt, F, Foreign, ForeignError(..), fail, readString)
6+
import Data.Foreign.Index (readProp)
67
import Data.Generic (class Generic, gShow, gEq)
78
import Data.YAML.Foreign.Encode
89

@@ -32,28 +33,28 @@ derive instance genericMobility :: Generic Mobility
3233
instance showMobility :: Show Mobility where show = gShow
3334
instance eqMobility :: Eq Mobility where eq = gEq
3435

35-
instance archiObjectIsForeign :: IsForeign GeoObject where
36-
read value = do
37-
name <- readProp "Name" value
38-
scale <- readProp "Scale" value
39-
points <- readProp "Points" value
40-
mobility <- readProp "Mobility" value
41-
coverage <- readProp "Coverage" value
42-
pure $ GeoObject { name, scale, points, mobility, coverage }
36+
readGeoObject :: Foreign -> F GeoObject
37+
readGeoObject value = do
38+
name <- readString =<< readProp "Name" value
39+
scale <- readNumber =<< readProp "Scale" value
40+
points <- traverse readPoint =<< readArray =<< readProp "Points" value
41+
mobility <- readMobility =<< readProp "Mobility" value
42+
coverage <- readNumber =<< readProp "Coverage" value
43+
pure $ GeoObject { name, scale, points, mobility, coverage }
4344

44-
instance pointIsForeign :: IsForeign Point where
45-
read value = do
46-
x <- readProp "X" value
47-
y <- readProp "Y" value
48-
pure $ Point x y
45+
readPoint :: Foreign -> F Point
46+
readPoint value = do
47+
x <- readInt =<< readProp "X" value
48+
y <- readInt =<< readProp "Y" value
49+
pure $ Point x y
4950

50-
instance mobilityIsForeign :: IsForeign Mobility where
51-
read value = do
52-
mob <- readString value
53-
case mob of
54-
"Fix" -> pure Fix
55-
"Flex" -> pure Flex
56-
_ -> fail $ JSONError "Mobility must be either Flex or Fix"
51+
readMobility :: Foreign -> F Mobility
52+
readMobility value = do
53+
mob <- readString value
54+
case mob of
55+
"Fix" -> pure Fix
56+
"Flex" -> pure Flex
57+
_ -> fail $ JSONError "Mobility must be either Flex or Fix"
5758

5859
instance pointToYAML :: ToYAML Point where
5960
toYAML (Point x y) =
@@ -75,4 +76,3 @@ instance archiObjectToYAML :: ToYAML GeoObject where
7576
, "Mobility" := o.mobility
7677
, "Coverage" := o.coverage
7778
]
78-

test/Main.purs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ module Test.Main where
33
import Control.Monad.Eff (Eff)
44
import Control.Monad.Except (runExcept)
55
import Data.Either (Either(..))
6-
import Data.Foreign (F)
7-
import Data.YAML.Foreign.Decode (readYAML)
6+
import Data.Foreign (F, readArray)
7+
import Data.YAML.Foreign.Decode (parseYAML)
88
import Data.YAML.Foreign.Encode (printYAML)
9-
import Prelude (Unit, bind, ($))
10-
import Test.Instances (GeoObject(..), Mobility(..), Point(..))
9+
import Data.Traversable (traverse)
10+
import Prelude (Unit, bind, ($), void, discard, (>>=))
11+
import Test.Instances (readGeoObject, readMobility, readPoint, GeoObject(..), Mobility(..), Point(..))
1112
import Test.Spec (describe, it)
1213
import Test.Spec.Assertions (shouldEqual)
1314
import Test.Spec.Reporter.Console (consoleReporter)
1415
import Test.Spec.Runner (RunnerEffects, run)
16+
import Control.Monad.Eff.Console (log, CONSOLE)
1517

1618
yamlInput :: String
1719
yamlInput = """
@@ -41,27 +43,27 @@ yamlInput = """
4143
"""
4244

4345
yamlOutput :: String
44-
yamlOutput = """- Coverage: 10
45-
Mobility: Fix
46-
Name: House
46+
yamlOutput = """- Mobility: Fix
4747
Points:
4848
- X: 10
4949
'Y': 10
5050
- X: 20
5151
'Y': 10
5252
- X: 5
5353
'Y': 5
54+
Coverage: 10
55+
Name: House
5456
Scale: 9.5
55-
- Coverage: 10
56-
Mobility: Fix
57-
Name: Tree
57+
- Mobility: Fix
5858
Points:
5959
- X: 1
6060
'Y': 1
6161
- X: 2
6262
'Y': 2
6363
- X: 0
6464
'Y': 0
65+
Coverage: 10
66+
Name: Tree
6567
Scale: 1
6668
"""
6769

@@ -85,13 +87,15 @@ parsedData =
8587

8688
main :: Eff (RunnerEffects ()) Unit
8789
main = run [consoleReporter] do
88-
describe "purescript-yaml" do
90+
void $ describe "purescript-yaml" do
8991
describe "decode" do
9092
it "Decodes YAML" do
91-
let decoded = (readYAML yamlInput) :: F (Array GeoObject)
93+
let decoded =
94+
(parseYAML yamlInput) >>=
95+
readArray >>=
96+
traverse readGeoObject
9297
(runExcept decoded) `shouldEqual` (Right parsedData)
93-
describe "encode" do
98+
void $ describe "encode" do
9499
it "Encodes YAML" $ do
95100
let encoded = printYAML parsedData
96101
encoded `shouldEqual` yamlOutput
97-

0 commit comments

Comments
 (0)