{-# LANGUAGE OverloadedStrings #-}

module HsDev.Tools.Hayoo (
	-- * Types
	HayooResult(..), HayooSymbol(..),
	hayooAsSymbol,
	-- * Search help online
	hayoo,
	-- * Utils
	untagDescription,

	-- * Reexportss
	module Control.Monad.Except
	) where

import Control.Arrow
import Control.Applicative
import Control.Lens (lens)
import Control.Monad.Except

import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as L
import Data.Either
import Data.Maybe (listToMaybe, fromJust)
import Network.HTTP.Client
import Network.URI (escapeURIString, isUnescapedInURIComponent)
import Data.String (fromString)
import qualified Data.Text as T (unpack, unlines)

import HsDev.Symbols
import HsDev.Tools.Base (replaceRx)
import HsDev.Util

-- | Hayoo response
data HayooResult = HayooResult {
	HayooResult -> Int
resultMax :: Int,
	HayooResult -> Int
resultOffset :: Int,
	HayooResult -> Int
resultCount :: Int,
	HayooResult -> [HayooSymbol]
resultResult :: [HayooSymbol] }
		deriving (HayooResult -> HayooResult -> Bool
(HayooResult -> HayooResult -> Bool)
-> (HayooResult -> HayooResult -> Bool) -> Eq HayooResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HayooResult -> HayooResult -> Bool
$c/= :: HayooResult -> HayooResult -> Bool
== :: HayooResult -> HayooResult -> Bool
$c== :: HayooResult -> HayooResult -> Bool
Eq, Eq HayooResult
Eq HayooResult
-> (HayooResult -> HayooResult -> Ordering)
-> (HayooResult -> HayooResult -> Bool)
-> (HayooResult -> HayooResult -> Bool)
-> (HayooResult -> HayooResult -> Bool)
-> (HayooResult -> HayooResult -> Bool)
-> (HayooResult -> HayooResult -> HayooResult)
-> (HayooResult -> HayooResult -> HayooResult)
-> Ord HayooResult
HayooResult -> HayooResult -> Bool
HayooResult -> HayooResult -> Ordering
HayooResult -> HayooResult -> HayooResult
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HayooResult -> HayooResult -> HayooResult
$cmin :: HayooResult -> HayooResult -> HayooResult
max :: HayooResult -> HayooResult -> HayooResult
$cmax :: HayooResult -> HayooResult -> HayooResult
>= :: HayooResult -> HayooResult -> Bool
$c>= :: HayooResult -> HayooResult -> Bool
> :: HayooResult -> HayooResult -> Bool
$c> :: HayooResult -> HayooResult -> Bool
<= :: HayooResult -> HayooResult -> Bool
$c<= :: HayooResult -> HayooResult -> Bool
< :: HayooResult -> HayooResult -> Bool
$c< :: HayooResult -> HayooResult -> Bool
compare :: HayooResult -> HayooResult -> Ordering
$ccompare :: HayooResult -> HayooResult -> Ordering
$cp1Ord :: Eq HayooResult
Ord, ReadPrec [HayooResult]
ReadPrec HayooResult
Int -> ReadS HayooResult
ReadS [HayooResult]
(Int -> ReadS HayooResult)
-> ReadS [HayooResult]
-> ReadPrec HayooResult
-> ReadPrec [HayooResult]
-> Read HayooResult
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [HayooResult]
$creadListPrec :: ReadPrec [HayooResult]
readPrec :: ReadPrec HayooResult
$creadPrec :: ReadPrec HayooResult
readList :: ReadS [HayooResult]
$creadList :: ReadS [HayooResult]
readsPrec :: Int -> ReadS HayooResult
$creadsPrec :: Int -> ReadS HayooResult
Read, Int -> HayooResult -> ShowS
[HayooResult] -> ShowS
HayooResult -> String
(Int -> HayooResult -> ShowS)
-> (HayooResult -> String)
-> ([HayooResult] -> ShowS)
-> Show HayooResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HayooResult] -> ShowS
$cshowList :: [HayooResult] -> ShowS
show :: HayooResult -> String
$cshow :: HayooResult -> String
showsPrec :: Int -> HayooResult -> ShowS
$cshowsPrec :: Int -> HayooResult -> ShowS
Show)

-- | Hayoo symbol
data HayooSymbol = HayooSymbol {
	HayooSymbol -> String
resultUri :: String,
	HayooSymbol -> String
tag :: String,
	HayooSymbol -> String
hayooPackage :: String,
	HayooSymbol -> String
hayooName :: String,
	HayooSymbol -> String
hayooSource :: String,
	HayooSymbol -> String
hayooDescription :: String,
	HayooSymbol -> String
hayooSignature :: String,
	HayooSymbol -> [String]
hayooModules :: [String],
	HayooSymbol -> Double
hayooScore :: Double,
	HayooSymbol -> String
hayooType :: String }
		deriving (HayooSymbol -> HayooSymbol -> Bool
(HayooSymbol -> HayooSymbol -> Bool)
-> (HayooSymbol -> HayooSymbol -> Bool) -> Eq HayooSymbol
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HayooSymbol -> HayooSymbol -> Bool
$c/= :: HayooSymbol -> HayooSymbol -> Bool
== :: HayooSymbol -> HayooSymbol -> Bool
$c== :: HayooSymbol -> HayooSymbol -> Bool
Eq, Eq HayooSymbol
Eq HayooSymbol
-> (HayooSymbol -> HayooSymbol -> Ordering)
-> (HayooSymbol -> HayooSymbol -> Bool)
-> (HayooSymbol -> HayooSymbol -> Bool)
-> (HayooSymbol -> HayooSymbol -> Bool)
-> (HayooSymbol -> HayooSymbol -> Bool)
-> (HayooSymbol -> HayooSymbol -> HayooSymbol)
-> (HayooSymbol -> HayooSymbol -> HayooSymbol)
-> Ord HayooSymbol
HayooSymbol -> HayooSymbol -> Bool
HayooSymbol -> HayooSymbol -> Ordering
HayooSymbol -> HayooSymbol -> HayooSymbol
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HayooSymbol -> HayooSymbol -> HayooSymbol
$cmin :: HayooSymbol -> HayooSymbol -> HayooSymbol
max :: HayooSymbol -> HayooSymbol -> HayooSymbol
$cmax :: HayooSymbol -> HayooSymbol -> HayooSymbol
>= :: HayooSymbol -> HayooSymbol -> Bool
$c>= :: HayooSymbol -> HayooSymbol -> Bool
> :: HayooSymbol -> HayooSymbol -> Bool
$c> :: HayooSymbol -> HayooSymbol -> Bool
<= :: HayooSymbol -> HayooSymbol -> Bool
$c<= :: HayooSymbol -> HayooSymbol -> Bool
< :: HayooSymbol -> HayooSymbol -> Bool
$c< :: HayooSymbol -> HayooSymbol -> Bool
compare :: HayooSymbol -> HayooSymbol -> Ordering
$ccompare :: HayooSymbol -> HayooSymbol -> Ordering
$cp1Ord :: Eq HayooSymbol
Ord, ReadPrec [HayooSymbol]
ReadPrec HayooSymbol
Int -> ReadS HayooSymbol
ReadS [HayooSymbol]
(Int -> ReadS HayooSymbol)
-> ReadS [HayooSymbol]
-> ReadPrec HayooSymbol
-> ReadPrec [HayooSymbol]
-> Read HayooSymbol
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [HayooSymbol]
$creadListPrec :: ReadPrec [HayooSymbol]
readPrec :: ReadPrec HayooSymbol
$creadPrec :: ReadPrec HayooSymbol
readList :: ReadS [HayooSymbol]
$creadList :: ReadS [HayooSymbol]
readsPrec :: Int -> ReadS HayooSymbol
$creadsPrec :: Int -> ReadS HayooSymbol
Read, Int -> HayooSymbol -> ShowS
[HayooSymbol] -> ShowS
HayooSymbol -> String
(Int -> HayooSymbol -> ShowS)
-> (HayooSymbol -> String)
-> ([HayooSymbol] -> ShowS)
-> Show HayooSymbol
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HayooSymbol] -> ShowS
$cshowList :: [HayooSymbol] -> ShowS
show :: HayooSymbol -> String
$cshow :: HayooSymbol -> String
showsPrec :: Int -> HayooSymbol -> ShowS
$cshowsPrec :: Int -> HayooSymbol -> ShowS
Show)

newtype HayooValue = HayooValue { HayooValue -> Either Value HayooSymbol
hayooValue :: Either Value HayooSymbol }

instance FromJSON HayooResult where
	parseJSON :: Value -> Parser HayooResult
parseJSON = String
-> (Object -> Parser HayooResult) -> Value -> Parser HayooResult
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"hayoo response" ((Object -> Parser HayooResult) -> Value -> Parser HayooResult)
-> (Object -> Parser HayooResult) -> Value -> Parser HayooResult
forall a b. (a -> b) -> a -> b
$ \Object
v -> Int -> Int -> Int -> [HayooSymbol] -> HayooResult
HayooResult (Int -> Int -> Int -> [HayooSymbol] -> HayooResult)
-> Parser Int
-> Parser (Int -> Int -> [HayooSymbol] -> HayooResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		(Object
v Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"max") Parser (Int -> Int -> [HayooSymbol] -> HayooResult)
-> Parser Int -> Parser (Int -> [HayooSymbol] -> HayooResult)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"offset") Parser (Int -> [HayooSymbol] -> HayooResult)
-> Parser Int -> Parser ([HayooSymbol] -> HayooResult)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"count") Parser ([HayooSymbol] -> HayooResult)
-> Parser [HayooSymbol] -> Parser HayooResult
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(([Either Value HayooSymbol] -> [HayooSymbol]
forall a b. [Either a b] -> [b]
rights ([Either Value HayooSymbol] -> [HayooSymbol])
-> ([HayooValue] -> [Either Value HayooSymbol])
-> [HayooValue]
-> [HayooSymbol]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HayooValue -> Either Value HayooSymbol)
-> [HayooValue] -> [Either Value HayooSymbol]
forall a b. (a -> b) -> [a] -> [b]
map HayooValue -> Either Value HayooSymbol
hayooValue) ([HayooValue] -> [HayooSymbol])
-> Parser [HayooValue] -> Parser [HayooSymbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
v Object -> Text -> Parser [HayooValue]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"result"))

instance Sourced HayooSymbol where
	sourcedName :: (Text -> f Text) -> HayooSymbol -> f HayooSymbol
sourcedName = (HayooSymbol -> Text)
-> (HayooSymbol -> Text -> HayooSymbol) -> Lens' HayooSymbol Text
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens HayooSymbol -> Text
g' HayooSymbol -> Text -> HayooSymbol
s' where
		g' :: HayooSymbol -> Text
g' = String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> (HayooSymbol -> String) -> HayooSymbol -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HayooSymbol -> String
hayooName
		s' :: HayooSymbol -> Text -> HayooSymbol
s' HayooSymbol
sym Text
n = HayooSymbol
sym { hayooName :: String
hayooName = Text -> String
T.unpack Text
n }
	sourcedModule :: (ModuleId -> f ModuleId) -> HayooSymbol -> f HayooSymbol
sourcedModule = (HayooSymbol -> ModuleId)
-> (HayooSymbol -> ModuleId -> HayooSymbol)
-> Lens' HayooSymbol ModuleId
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens HayooSymbol -> ModuleId
g' HayooSymbol -> ModuleId -> HayooSymbol
forall p p. p -> p -> p
s' where
		g' :: HayooSymbol -> ModuleId
g' HayooSymbol
h = Text -> ModuleLocation -> ModuleId
ModuleId Text
nm (Text -> ModuleLocation
OtherLocation (Text -> ModuleLocation) -> Text -> ModuleLocation
forall a b. (a -> b) -> a -> b
$ String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
resultUri HayooSymbol
h) where
			nm :: Text
nm = Text -> (String -> Text) -> Maybe String -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
forall a. Monoid a => a
mempty String -> Text
forall a. IsString a => String -> a
fromString (Maybe String -> Text) -> Maybe String -> Text
forall a b. (a -> b) -> a -> b
$ [String] -> Maybe String
forall a. [a] -> Maybe a
listToMaybe ([String] -> Maybe String) -> [String] -> Maybe String
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> [String]
hayooModules HayooSymbol
h
		s' :: p -> p -> p
s' p
h p
_ = p
h
	sourcedDocs :: (Text -> f Text) -> HayooSymbol -> f HayooSymbol
sourcedDocs Text -> f Text
f HayooSymbol
h = (\Text
d' -> HayooSymbol
h { hayooDescription :: String
hayooDescription = Text -> String
T.unpack Text
d' }) (Text -> HayooSymbol) -> f Text -> f HayooSymbol
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> f Text
f (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
hayooDescription HayooSymbol
h)

instance Documented HayooSymbol where
	brief :: HayooSymbol -> Text
brief HayooSymbol
f
		| HayooSymbol -> String
hayooType HayooSymbol
f String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"function" = String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
hayooName HayooSymbol
f String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" :: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HayooSymbol -> String
hayooSignature HayooSymbol
f
		| Bool
otherwise = String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
hayooType HayooSymbol
f String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HayooSymbol -> String
hayooName HayooSymbol
f
	detailed :: HayooSymbol -> Text
detailed HayooSymbol
f = [Text] -> Text
T.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> [Text]
forall a. (Sourced a, Documented a) => a -> [Text]
defaultDetailed HayooSymbol
f [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (String -> Text) -> [String] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map String -> Text
forall a. IsString a => String -> a
fromString [String]
online where
		online :: [String]
online = [
			String
"", String
"Hayoo online documentation", String
"",
			String
"Package: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HayooSymbol -> String
hayooPackage HayooSymbol
f,
			String
"Hackage URL: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HayooSymbol -> String
resultUri HayooSymbol
f]

instance FromJSON HayooSymbol where
	parseJSON :: Value -> Parser HayooSymbol
parseJSON = String
-> (Object -> Parser HayooSymbol) -> Value -> Parser HayooSymbol
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"symbol" ((Object -> Parser HayooSymbol) -> Value -> Parser HayooSymbol)
-> (Object -> Parser HayooSymbol) -> Value -> Parser HayooSymbol
forall a b. (a -> b) -> a -> b
$ \Object
v -> String
-> String
-> String
-> String
-> String
-> String
-> String
-> [String]
-> Double
-> String
-> HayooSymbol
HayooSymbol (String
 -> String
 -> String
 -> String
 -> String
 -> String
 -> String
 -> [String]
 -> Double
 -> String
 -> HayooSymbol)
-> Parser String
-> Parser
     (String
      -> String
      -> String
      -> String
      -> String
      -> String
      -> [String]
      -> Double
      -> String
      -> HayooSymbol)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultUri") Parser
  (String
   -> String
   -> String
   -> String
   -> String
   -> String
   -> [String]
   -> Double
   -> String
   -> HayooSymbol)
-> Parser String
-> Parser
     (String
      -> String
      -> String
      -> String
      -> String
      -> [String]
      -> Double
      -> String
      -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"tag") Parser
  (String
   -> String
   -> String
   -> String
   -> String
   -> [String]
   -> Double
   -> String
   -> HayooSymbol)
-> Parser String
-> Parser
     (String
      -> String
      -> String
      -> String
      -> [String]
      -> Double
      -> String
      -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultPackage") Parser
  (String
   -> String
   -> String
   -> String
   -> [String]
   -> Double
   -> String
   -> HayooSymbol)
-> Parser String
-> Parser
     (String
      -> String -> String -> [String] -> Double -> String -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultName") Parser
  (String
   -> String -> String -> [String] -> Double -> String -> HayooSymbol)
-> Parser String
-> Parser
     (String -> String -> [String] -> Double -> String -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultSource") Parser
  (String -> String -> [String] -> Double -> String -> HayooSymbol)
-> Parser String
-> Parser (String -> [String] -> Double -> String -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultDescription") Parser (String -> [String] -> Double -> String -> HayooSymbol)
-> Parser String
-> Parser ([String] -> Double -> String -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultSignature") Parser ([String] -> Double -> String -> HayooSymbol)
-> Parser [String] -> Parser (Double -> String -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser [String]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultModules") Parser (Double -> String -> HayooSymbol)
-> Parser Double -> Parser (String -> HayooSymbol)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser Double
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultScore") Parser (String -> HayooSymbol)
-> Parser String -> Parser HayooSymbol
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		(Object
v Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"resultType")

instance FromJSON HayooValue where
	parseJSON :: Value -> Parser HayooValue
parseJSON Value
v = Either Value HayooSymbol -> HayooValue
HayooValue (Either Value HayooSymbol -> HayooValue)
-> Parser (Either Value HayooSymbol) -> Parser HayooValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((HayooSymbol -> Either Value HayooSymbol
forall a b. b -> Either a b
Right (HayooSymbol -> Either Value HayooSymbol)
-> Parser HayooSymbol -> Parser (Either Value HayooSymbol)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser HayooSymbol
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v) Parser (Either Value HayooSymbol)
-> Parser (Either Value HayooSymbol)
-> Parser (Either Value HayooSymbol)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Either Value HayooSymbol -> Parser (Either Value HayooSymbol)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> Either Value HayooSymbol
forall a b. a -> Either a b
Left Value
v))

-- | 'HayooFunction' as 'Symbol'
hayooAsSymbol :: HayooSymbol -> Maybe Symbol
hayooAsSymbol :: HayooSymbol -> Maybe Symbol
hayooAsSymbol HayooSymbol
f
	| HayooSymbol -> String
hayooType HayooSymbol
f String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"function", String
"type", String
"newtype", String
"data", String
"class"] = Symbol -> Maybe Symbol
forall a. a -> Maybe a
Just Symbol :: SymbolId -> Maybe Text -> Maybe Position -> SymbolInfo -> Symbol
Symbol {
		_symbolId :: SymbolId
_symbolId = SymbolId :: Text -> ModuleId -> SymbolId
SymbolId {
			_symbolName :: Text
_symbolName = String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
hayooName HayooSymbol
f,
			_symbolModule :: ModuleId
_symbolModule = ModuleId :: Text -> ModuleLocation -> ModuleId
ModuleId {
				_moduleName :: Text
_moduleName = String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall a. [a] -> a
head ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> [String]
hayooModules HayooSymbol
f,
				_moduleLocation :: ModuleLocation
_moduleLocation = Text -> ModuleLocation
OtherLocation (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
resultUri HayooSymbol
f) } },
		_symbolDocs :: Maybe Text
_symbolDocs = Text -> Maybe Text
forall a. a -> Maybe a
Just (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ ShowS
addOnline ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
untagDescription ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
hayooDescription HayooSymbol
f),
		_symbolPosition :: Maybe Position
_symbolPosition = Maybe Position
forall a. Maybe a
Nothing,
		_symbolInfo :: SymbolInfo
_symbolInfo = SymbolInfo
info }
	| Bool
otherwise = Maybe Symbol
forall a. Maybe a
Nothing
	where
		-- Add other info
		addOnline :: ShowS
addOnline String
d = [String] -> String
unlines [
			String
d, String
"",
			String
"Hayoo online documentation",
			String
"",
			String
"Package: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HayooSymbol -> String
hayooPackage HayooSymbol
f,
			String
"Hackage URL: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HayooSymbol -> String
resultUri HayooSymbol
f]

		info :: SymbolInfo
info
			| HayooSymbol -> String
hayooType HayooSymbol
f String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"function" = Maybe Text -> SymbolInfo
Function (Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HayooSymbol -> String
hayooSignature HayooSymbol
f)
			| HayooSymbol -> String
hayooType HayooSymbol
f String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"type", String
"newtype", String
"data", String
"class"] = (Maybe ([Text] -> [Text] -> SymbolInfo)
-> [Text] -> [Text] -> SymbolInfo
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe ([Text] -> [Text] -> SymbolInfo)
 -> [Text] -> [Text] -> SymbolInfo)
-> Maybe ([Text] -> [Text] -> SymbolInfo)
-> [Text]
-> [Text]
-> SymbolInfo
forall a b. (a -> b) -> a -> b
$ String
-> [(String, [Text] -> [Text] -> SymbolInfo)]
-> Maybe ([Text] -> [Text] -> SymbolInfo)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (HayooSymbol -> String
hayooType HayooSymbol
f) [(String, [Text] -> [Text] -> SymbolInfo)]
ctors) [] []
			| Bool
otherwise = String -> SymbolInfo
forall a. HasCallStack => String -> a
error String
"Impossible"
		ctors :: [(String, [Text] -> [Text] -> SymbolInfo)]
ctors = [(String
"type", [Text] -> [Text] -> SymbolInfo
Type), (String
"newtype", [Text] -> [Text] -> SymbolInfo
NewType), (String
"data", [Text] -> [Text] -> SymbolInfo
Data), (String
"class", [Text] -> [Text] -> SymbolInfo
Class)]

-- | Search hayoo
hayoo :: Manager -> String -> Maybe Int -> ExceptT String IO HayooResult
hayoo :: Manager -> String -> Maybe Int -> ExceptT String IO HayooResult
hayoo Manager
m String
q Maybe Int
page = do
	ByteString
resp <- IO ByteString -> ExceptT String IO ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> ExceptT String IO ByteString)
-> IO ByteString -> ExceptT String IO ByteString
forall a b. (a -> b) -> a -> b
$ do
		Request
req <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest (String -> IO Request) -> String -> IO Request
forall a b. (a -> b) -> a -> b
$ ShowS -> (Int -> ShowS) -> Maybe Int -> ShowS
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ShowS
forall a. a -> a
id Int -> ShowS
addPage Maybe Int
page ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
"http://hayoo.fh-wedel.de/json/?query=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Char -> Bool) -> ShowS
escapeURIString Char -> Bool
isUnescapedInURIComponent String
q
		Response ByteString
resp <- Request -> Manager -> IO (Response ByteString)
httpLbs Request
req Manager
m
		ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Response ByteString -> ByteString
forall body. Response body -> body
responseBody Response ByteString
resp
	IO (Either String HayooResult) -> ExceptT String IO HayooResult
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (IO (Either String HayooResult) -> ExceptT String IO HayooResult)
-> IO (Either String HayooResult) -> ExceptT String IO HayooResult
forall a b. (a -> b) -> a -> b
$ Either String HayooResult -> IO (Either String HayooResult)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String HayooResult -> IO (Either String HayooResult))
-> Either String HayooResult -> IO (Either String HayooResult)
forall a b. (a -> b) -> a -> b
$ ByteString -> Either String HayooResult
forall a. FromJSON a => ByteString -> Either String a
eitherDecode ByteString
resp
	where
		addPage :: Int -> String -> String
		addPage :: Int -> ShowS
addPage Int
p String
s = String
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"&page=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
p

-- | Remove tags in description
untagDescription :: String -> String
untagDescription :: ShowS
untagDescription = String -> String -> ShowS
replaceRx String
"</?\\w+[^>]*>" String
""