module Data.Docs.Docs
( Documentation(..)
, Field(..)
, Docs(..)
, genDocs
, genDocsWithValues
, genValues
, genFields
) where
import Data.Text (Text, pack)
import qualified Data.Text as T
import Data.Docs.TypeName (GTypeName)
import qualified Data.Docs.TypeName as TypeName
import Data.Docs.Selectors (Selectors(..))
import Data.Data (Proxy(..), TypeRep)
import GHC.Generics (Generic, Rep)
class Docs a where
docs :: Proxy a -> Documentation
default docs :: (Generic a, GTypeName (Rep a), Selectors (Rep a)) => Proxy a -> Documentation
docs = genDocs ""
type FieldName = Text
type TypeName = Text
data Documentation = Documentation
{ typeName :: TypeName
, fields :: [Field]
, description :: Text
, enumeratedValues :: [Text]
} deriving (Show, Eq)
data Field = Field
{ fieldName :: FieldName
, fieldType :: TypeName
, isRequired :: Bool
} deriving (Show, Eq)
genDocs :: forall a. (Generic a, GTypeName (Rep a), Selectors (Rep a)) => Text -> Proxy a -> Documentation
genDocs d p = Documentation
{ typeName = pack $ TypeName.typeName p
, description = d
, fields = genFields p
, enumeratedValues = []
}
genDocsWithValues :: forall a. (Generic a, GTypeName (Rep a), Selectors (Rep a), Bounded a, Enum a, Show a) => Text -> Proxy a -> Documentation
genDocsWithValues d p =
(genDocs d p)
{ enumeratedValues = genValues p }
genFields :: forall a. (Selectors (Rep a)) => Proxy a -> [Field]
genFields _ = map (uncurry toField . selectorToText) $ selectors (Proxy :: Proxy (Rep a))
genValues :: forall a. (Enum a, Bounded a, Show a) => Proxy a -> [Text]
genValues _ = map (pack . show) ([minBound..] :: [a])
selectorToText :: (String, TypeRep) -> (Text, [Text])
selectorToText (s, t) = (pack s, T.words $ pack $ show t)
toField :: Text -> [Text] -> Field
toField s ("Maybe":t) = Field s (T.concat t) False
toField s t = Field s (T.concat t) True