|
2 | 2 |
|
3 | 3 | module Data.Foreign.Class |
4 | 4 | ( class IsForeign |
| 5 | + , class AsForeign |
| 6 | + , (.=) |
5 | 7 | , read |
6 | 8 | , readJSON |
7 | 9 | , readWith |
8 | 10 | , readProp |
| 11 | + , write |
| 12 | + , writeProp |
9 | 13 | ) where |
10 | 14 |
|
11 | 15 | import Prelude |
12 | 16 |
|
13 | 17 | import Data.Array (range, zipWith, length) |
14 | 18 | import Data.Either (Either(..), either) |
15 | | -import Data.Foreign (F, Foreign, ForeignError(..), parseJSON, readArray, readInt, readNumber, readBoolean, readChar, readString) |
| 19 | +import Data.Foreign (F, Foreign, ForeignError(..), Prop(..), parseJSON, readArray, readInt, readNumber, readBoolean, readChar, readString, toForeign) |
16 | 20 | import Data.Foreign.Index (class Index, errorAt, (!)) |
17 | | -import Data.Foreign.Null (Null, readNull) |
18 | | -import Data.Foreign.NullOrUndefined (NullOrUndefined, readNullOrUndefined) |
19 | | -import Data.Foreign.Undefined (Undefined, readUndefined) |
| 21 | +import Data.Foreign.Null (Null(..), readNull, writeNull) |
| 22 | +import Data.Foreign.NullOrUndefined (NullOrUndefined(..), readNullOrUndefined) |
| 23 | +import Data.Foreign.Undefined (Undefined(..), readUndefined, writeUndefined) |
20 | 24 | import Data.Traversable (sequence) |
| 25 | +import Data.Maybe (maybe) |
21 | 26 |
|
22 | 27 | -- | A type class instance for this class can be written for a type if it |
23 | 28 | -- | is possible to attempt to _safely_ coerce a `Foreign` value to that |
@@ -75,3 +80,44 @@ readWith f value = either (Left <<< f) Right (read value) |
75 | 80 | -- | Attempt to read a property of a foreign value at the specified index |
76 | 81 | readProp :: forall a i. (IsForeign a, Index i) => i -> Foreign -> F a |
77 | 82 | readProp prop value = value ! prop >>= readWith (errorAt prop) |
| 83 | + |
| 84 | +-- | A type class to convert to a `Foreign` value. |
| 85 | +-- | |
| 86 | +-- | Instances are provided for standard data structures. |
| 87 | +class AsForeign a where |
| 88 | + write :: a -> Foreign |
| 89 | + |
| 90 | +instance foreignAsForeign :: AsForeign Foreign where |
| 91 | + write = id |
| 92 | + |
| 93 | +instance stringAsForeign :: AsForeign String where |
| 94 | + write = toForeign |
| 95 | + |
| 96 | +instance charAsForeign :: AsForeign Char where |
| 97 | + write = toForeign |
| 98 | + |
| 99 | +instance booleanAsForeign :: AsForeign Boolean where |
| 100 | + write = toForeign |
| 101 | + |
| 102 | +instance numberAsForeign :: AsForeign Number where |
| 103 | + write = toForeign |
| 104 | + |
| 105 | +instance intAsForeign :: AsForeign Int where |
| 106 | + write = toForeign |
| 107 | + |
| 108 | +instance arrayAsForeign :: (AsForeign a) => AsForeign (Array a) where |
| 109 | + write = toForeign <<< map write |
| 110 | + |
| 111 | +instance nullAsForeign :: (AsForeign a) => AsForeign (Null a) where |
| 112 | + write (Null a) = maybe writeNull write a |
| 113 | + |
| 114 | +instance undefinedAsForeign :: (AsForeign a) => AsForeign (Undefined a) where |
| 115 | + write (Undefined a) = maybe writeUndefined write a |
| 116 | + |
| 117 | +instance nullOrUndefinedAsForeign :: (AsForeign a) => AsForeign (NullOrUndefined a) where |
| 118 | + write (NullOrUndefined a) = write (Null a) |
| 119 | + |
| 120 | +infixl 8 writeProp as .= |
| 121 | + |
| 122 | +writeProp :: forall a. (AsForeign a) => String -> a -> Prop |
| 123 | +writeProp k v = Prop { key: k, value: write v } |
0 commit comments