{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-} module Oden.Go.Types ( Type(..) ) where import qualified Data.Aeson as A import Data.Aeson ((.:), parseJSON) import qualified Data.Aeson.Types as AT import qualified Data.HashMap.Strict as HM import qualified Data.Text as T data Type = Basic String Bool | Pointer Type | Array Int Type | Slice Type | Signature Bool (Maybe Type) [Type] [Type] | Named String String Type | Interface | Unsupported String deriving (Show, Eq) optOrNull :: A.FromJSON a => HM.HashMap T.Text AT.Value -> T.Text -> AT.Parser (Maybe a) o `optOrNull` k = case HM.lookup k o of Just AT.Null -> return Nothing Just v -> parseJSON v Nothing -> return Nothing instance A.FromJSON Type where parseJSON (AT.Object o) = do kind :: String <- o .: "kind" case kind of "basic" -> Basic <$> o .: "name" <*> o .: "untyped" "pointer" -> Pointer <$> o .: "inner" "interface" -> return Interface "array" -> Array <$> o .: "length" <*> o .: "inner" "slice" -> Slice <$> o .: "inner" "signature" -> Signature <$> o .: "variadic" <*> o `optOrNull` "recv" <*> o .: "arguments" <*> o .: "returns" "named" -> Named <$> o .: "pkg" <*> o .: "name" <*> o .: "underlying" "unsupported" -> Unsupported <$> o .: "name" k -> fail ("Unknown kind: " ++ k) parseJSON v = fail ("Unexpected: " ++ show v)