@@ -0,0 +1,280 @@
1+{-# OPTIONS_GHC -Wall #-}
2+{-# LANGUAGE OverloadedStrings #-}
4+ ( Decoder, Error(..), decode, parse
5+ , text, bool, int, float
8+ , map, map2, succeed, fail, andThen
10+ , moduleName, packageName
15+import Data.Text (Text)
16+import Prelude hiding (fail, map, maybe)
18+import qualified Control.Monad as Monad
19+import qualified Data.Aeson as Aeson
20+import qualified Data.ByteString.Lazy as BS
21+import qualified Data.HashMap.Lazy as HashMap
22+import qualified Data.Scientific as Scientific
23+import qualified Data.Text as Text
24+import qualified Data.Vector as Vector
26+import qualified Elm.Compiler.Module as Module
27+import qualified Elm.Package as Pkg
36+ { _run :: (Error -> Error) -> Aeson.Value -> Either Error a
43+ | Failure Aeson.Value String
46+decode :: Decoder a -> Aeson.Value -> Either Error a
47+decode decoder value =
48+ _run decoder id value
51+parse :: Decoder a -> BS.ByteString -> Either (Maybe Error) a
52+parse decoder bytestring =
53+ case Aeson.eitherDecode bytestring of
58+ case decode decoder json of
72+ Decoder $ \mkError value ->
78+ Left (mkError (Failure value "a string"))
83+ Decoder $ \mkError value ->
85+ Aeson.Bool boolean ->
89+ Left (mkError (Failure value "a boolean"))
94+ Decoder $ \mkError value ->
96+ Aeson.Number number ->
97+ case Scientific.toBoundedInteger number of
99+ Left (mkError (Failure value "an integer"))
105+ Left (mkError (Failure value "an integer"))
108+float :: Decoder Float
110+ Decoder $ \mkError value ->
112+ Aeson.Number number ->
113+ Right (Scientific.toRealFloat number)
116+ Left (mkError (Failure value "a float"))
123+list :: Decoder a -> Decoder [a]
125+ Decoder $ \mkError value ->
127+ Aeson.Array vector ->
129+ Vector.imapM (\i v -> run (mkError . Index i) v) vector
132+ Left (mkError (Failure value "an array"))
135+dict :: Decoder a -> Decoder (HashMap.HashMap Text a)
137+ Decoder $ \mkError value ->
139+ Aeson.Object hashMap ->
140+ HashMap.traverseWithKey (\k v -> run (mkError . Field k) v) hashMap
143+ Left (mkError (Failure value "an object"))
146+maybe :: Decoder a -> Decoder (Maybe a)
147+maybe (Decoder run) =
148+ Decoder $ \mkError value ->
149+ case run mkError value of
161+field :: Text -> Decoder a -> Decoder a
162+field name (Decoder run) =
163+ Decoder $ \mkError value ->
165+ Aeson.Object hashMap ->
166+ case HashMap.lookup name hashMap of
168+ run (mkError . Field name) v
172+ Failure value ("a \"" ++ Text.unpack name ++ "\" field")
175+ Left (mkError (Failure value "an object"))
178+at :: [Text] -> Decoder a -> Decoder a
180+ foldr field decoder names
187+map :: (a -> value) -> Decoder a -> Decoder value
188+map func (Decoder run) =
189+ Decoder $ \mkError value ->
190+ func <$> run mkError value
193+map2 :: (a -> b -> value) -> Decoder a -> Decoder b -> Decoder value
194+map2 func (Decoder runA) (Decoder runB) =
195+ Decoder $ \mkError value ->
197+ <$> runA mkError value
198+ <*> runB mkError value
201+apply :: Decoder (a -> b) -> Decoder a -> Decoder b
202+apply (Decoder runFunc) (Decoder runArg) =
203+ Decoder $ \mkError value ->
204+ do func <- runFunc mkError value
205+ arg <- runArg mkError value
209+instance Functor Decoder where
214+instance Applicative Decoder where
222+instance Monad Decoder where
226+ (>>=) decoder callback =
227+ andThen callback decoder
237+succeed :: a -> Decoder a
239+ Decoder $ \_ _ -> Right a
242+fail :: String -> Decoder a
244+ Decoder $ \mkError value ->
245+ Left (mkError (Failure value msg))
248+andThen :: (a -> Decoder b) -> Decoder a -> Decoder b
249+andThen callback (Decoder runA) =
250+ Decoder $ \mkError value ->
251+ do a <- runA mkError value
252+ let (Decoder runB) = callback a
257+-- ELM SPECIFIC STUFF
260+moduleName :: Decoder Module.Raw
263+ case Module.nameFromText txt of
265+ fail "a module name like \"Html.Events\""
271+packageName :: Decoder Pkg.Name
274+ case Pkg.fromText txt of
276+ fail "a valid project name, like \"elm-lang/core\""