-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Documentation DSL for persistent entities -- -- A convenient DSL that allows you to attach documentation to persistent -- database entities @package persistent-documentation @version 0.1.0.0 module Data.SemiMap -- | A newtype around Map which uses unionWith -- '(<>)' for the semigroup and monoid instance. newtype SemiMap k v SemiMap :: Map k v -> SemiMap k v [unSemiMap] :: SemiMap k v -> Map k v instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Data.SemiMap.SemiMap k v) instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.SemiMap.SemiMap k v) instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.SemiMap.SemiMap k v) instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Semigroup (Data.SemiMap.SemiMap k v) instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Monoid (Data.SemiMap.SemiMap k v) module Data.StrMap -- | A StrMap is sort of like a HashMap, but sorts the keys -- on a Text representation. Additionally, it has more useful -- Semigroup and Monoid instances that '(<>)' the -- values when present. newtype StrMap k a StrMap :: Map (AsStr k) a -> StrMap k a -- | Insert a value into a StrMap. insert :: Show k => k -> a -> StrMap k a -> StrMap k a -- | Lookup a value in the StrMap. lookup :: Show k => k -> StrMap k a -> Maybe a -- | A datatype for representing the keys of entries in a StrMap. -- Contains the original value as well as the Textual -- representation of that value. -- -- The Eq and Ord instances only use the Text value. data AsStr k AsStr :: Text -> k -> AsStr k [asStrText] :: AsStr k -> Text [asStrValue] :: AsStr k -> k -- | Pack a value into an AsStr of that value. asStr :: Show k => k -> AsStr k instance (GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.StrMap.StrMap k a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.StrMap.StrMap k a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.StrMap.StrMap k a) instance GHC.Show.Show k => GHC.Show.Show (Data.StrMap.AsStr k) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.StrMap.StrMap k a) instance GHC.Base.Semigroup a => GHC.Base.Monoid (Data.StrMap.StrMap k a) instance GHC.Classes.Eq (Data.StrMap.AsStr k) instance GHC.Classes.Ord (Data.StrMap.AsStr k) -- | This module defines the helpers and internal types that are used in -- the documentation DSL. module Database.Persist.Documentation.Internal -- | Given a list of FieldDefs, this associates each FieldDef -- with the additional documentation comment provided in the -- StrMap (SomeField rec) Text for that -- entity, if any is present. -- -- Precondition: The [FieldDef] comes from the -- PersistEntity rec that this is called for. Doing eg: -- --
-- alignFields -- (entityFields (entityDef (Proxy :: Proxy User))) -- (strMap :: StrMap (SomeField Order) Text) ---- -- will be extremely weird. alignFields :: forall rec. RC rec => [FieldDef] -> StrMap (SomeField rec) Text -> [FieldDef] -- | Formats the SomeField rec in the keys of the -- Map to be formatted in the same way as the HaskellName -- present in a FieldDef. asHaskellNames :: forall rec. RC rec => StrMap (SomeField rec) Text -> Map Text Text -- | A type for defining documentation for a schema. newtype EntityDoc' a ED :: Writer SchemaDocs a -> EntityDoc' a -- | The SchemaDocs maps a TypeRep of the Entity -- rec that is documented to the SomeDocs for that entity. type SchemaDocs = SemiMap TypeRep SomeDocs -- | A wrapper around EntityDocs that allows them to be stored in a -- list together. Contains the RC constraint alias, which will -- ensure that all necessary constraints for document rendering are -- packaged in. data SomeDocs [SomeDocs] :: RC rec => EntityDocs rec -> SomeDocs -- | Expand this constraint synonym to pack necessary constraints in with -- the EntityDocs type. Used in a few places to ensure that -- constraints are easy to modify in one place. type RC rec = (Typeable rec) -- | EntityDocs contain the documentation comment for the -- Entity rec that is being documented, as well as a map -- of documentation for the fields of that entity. data EntityDocs rec EntityDocs :: Text -> StrMap (SomeField rec) Text -> EntityDocs rec [entityDocumentation] :: EntityDocs rec -> Text [fieldDocumentation] :: EntityDocs rec -> StrMap (SomeField rec) Text -- | An expression of EntityDoc is used to document the persistent -- schema. To construct an EntityDoc, you'll use the Entity -- constructor and the '(--^)' operator. Everything to the right of the -- '(--^)' operator is a 'FieldDoc rec' for the given entity. -- -- This type is a monad, and you can use do notation to sequence -- the documentation. -- --
-- doc :: EntityDoc -- doc = do -- User --^ "Documentation for a User" -- Dog --^ "Documentation for a Dog" --type EntityDoc = EntityDoc' () -- | A FieldDoc expression provides documentation for the given -- Entity. This type is a Monad and you will want to use -- do notation to create this. -- -- There are two ways to create FieldDoc lines: -- --
-- x :: EntityDoc -- x = do -- User --^ do -- "This comment is for the entity User." -- UserName # "This comment is for a field."" --(--^) :: forall a r. (KnowResult a ~ r, Typeable r, RC r) => a -> FieldDoc r -> EntityDoc -- | Write documentation for the given EntityField. -- --
-- x :: EntityDoc -- x = do -- User --^ do -- "This comment is for the entity User." -- UserName # "This comment is for a field."" --(#) :: FC rec typ => EntityField rec typ -> Text -> FieldDoc rec instance Control.Monad.Writer.Class.MonadWriter (Database.Persist.Documentation.Internal.EntityDocs rec) (Database.Persist.Documentation.Internal.FieldDoc' rec) instance GHC.Base.Monad (Database.Persist.Documentation.Internal.FieldDoc' rec) instance GHC.Base.Applicative (Database.Persist.Documentation.Internal.FieldDoc' rec) instance GHC.Base.Functor (Database.Persist.Documentation.Internal.FieldDoc' rec) instance Control.Monad.Writer.Class.MonadWriter Database.Persist.Documentation.Internal.SchemaDocs Database.Persist.Documentation.Internal.EntityDoc' instance GHC.Base.Monad Database.Persist.Documentation.Internal.EntityDoc' instance GHC.Base.Applicative Database.Persist.Documentation.Internal.EntityDoc' instance GHC.Base.Functor Database.Persist.Documentation.Internal.EntityDoc' instance (a Data.Type.Equality.~ ()) => Data.String.IsString (Database.Persist.Documentation.Internal.FieldDoc' s a) instance GHC.Base.Semigroup Database.Persist.Documentation.Internal.SomeDocs instance GHC.Base.Semigroup (Database.Persist.Documentation.Internal.EntityDocs rec) instance GHC.Base.Monoid (Database.Persist.Documentation.Internal.EntityDocs rec) instance (forall typ. GHC.Show.Show (Database.Persist.Class.PersistEntity.EntityField rec typ)) => GHC.Show.Show (Database.Persist.Documentation.Internal.SomeField rec) -- | This module contains code for documenting a set of persistent -- entity definitions. All the library provides is a means to render a -- Markdown document with table and column documentation and comments. A -- further expansion could use the information here to generate -- PostgreSQL COMMENTs on the fields and tables too. -- --
-- share [mkPersist sqlSettings] [persistUpperCase| -- User -- firstName Text.Text -- active Bool -- deriving Show Eq Read Ord -- |] ---- -- The persistUpperCase QuasiQuoter parses the block of text and -- returns a value of type [EntityDef]. We need to get -- our hands on that definition so we can document it. -- -- Due to GHC staging restrictions, we have to extract the QuasiQuoter -- (or file parser) into a separate module: -- --
-- module Entities where -- -- entityDefs :: [EntityDef] -- entityDefs = [persistUpperCase| -- User -- firstName Text.Text -- active Bool -- deriving Show Eq Read Ord -- |] ---- -- Now, we'll import that value, and use it with the Template Haskell -- function. We also need to use deriveShowFields to derive -- instances of Show for the EntityFields that are -- generated. -- --
-- share [mkPersist sqlSettings, deriveShowFields] entityDefs ---- -- That's all the setup we need to start writing documentation for our -- entites. -- --
-- docs :: [EntityDef] -- docs = document entityDefs (pure ()) ---- -- The EntityDoc type is a monad, and we'll use do -- notation to sequence multiple entity definitions. -- --
-- docs :: [EntityDef] -- docs = document entityDefs $ do -- User --^ do -- pure () ---- -- The '(--^)' operator mimics the Haddock comment syntax. We use the -- constructor of the entity (in this case, User). On the right, -- we provide documentation for the entity. The right hand expression -- will have the type FieldDoc, and we can use do -- notation to construct it. -- -- We can use string literals to document the entity itself, with the -- OverloadedStrings extension enabled. The string literals are -- concatenated, and used to provide entity-level comments. You'll need -- to manage whitespace yourself, though. -- --
-- docs :: [EntityDef] -- docs = document entityDefs $ do -- User --^ do -- "This is user documentation. " -- "You can have multiple lines, but you need to watch out for spaces. " -- "The lines will be combined." ---- -- We can also document the entity fields. We do this using the '(#)' -- operator. -- --
-- docs :: [EntityDef] -- docs = document entityDefs $ do -- User --^ do -- "This is user documentation. " -- "You can have multiple lines, but you need to watch out for spaces. " -- "The lines will be combined." -- -- UserFirstName # "The user's first name." -- UserActive # "Whether or not the user is able to log in." ---- -- This attaches the comment to the entity field. -- --
-- renderedDocs :: Text -- renderedDocs = render markdownTableRenderer docs --module Database.Persist.Documentation -- | This function accepts a list of EntityDef and an -- EntityDoc block, and substitutes the entityComments and -- fieldComments from the EntityDoc. document :: [EntityDef] -> EntityDoc -> [EntityDef] -- | Define documentation for an entity. The left-hand side takes the -- Entity constructor, and the right hand side takes a -- FieldDoc expression that documents the entity and it's fields. -- --
-- x :: EntityDoc -- x = do -- User --^ do -- "This comment is for the entity User." -- UserName # "This comment is for a field."" --(--^) :: forall a r. (KnowResult a ~ r, Typeable r, RC r) => a -> FieldDoc r -> EntityDoc -- | Write documentation for the given EntityField. -- --
-- x :: EntityDoc -- x = do -- User --^ do -- "This comment is for the entity User." -- UserName # "This comment is for a field."" --(#) :: FC rec typ => EntityField rec typ -> Text -> FieldDoc rec -- | An expression of EntityDoc is used to document the persistent -- schema. To construct an EntityDoc, you'll use the Entity -- constructor and the '(--^)' operator. Everything to the right of the -- '(--^)' operator is a 'FieldDoc rec' for the given entity. -- -- This type is a monad, and you can use do notation to sequence -- the documentation. -- --
-- doc :: EntityDoc -- doc = do -- User --^ "Documentation for a User" -- Dog --^ "Documentation for a Dog" --type EntityDoc = EntityDoc' () -- | A FieldDoc expression provides documentation for the given -- Entity. This type is a Monad and you will want to use -- do notation to create this. -- -- There are two ways to create FieldDoc lines: -- --
-- entityDefs :: [EntityDef] -- entityDefs = [persistUpperCase| -- User -- firstName Text.Text -- active Bool -- deriving Show Eq Read Ord -- |] ---- -- and a doc block like: -- --
-- docs :: [EntityDef] -- docs = document entityDefs $ do -- User --^ do -- "you can use string literals to write documentation for the entity itself. " -- "The strings will be mappended together, so you'll need to handle " -- "whitespace yourself." -- UserFirstName # "The user's first name." -- UserActive # "Whether or not the user is able to log in." -- UserId # "You can document the user's ID field." ---- -- This will rende the given Markdown output: -- --
-- # User -- -- you can use string literals to write documentation for the entity itself. The strings will be -- mappended together, so you'll need to handle whitespace yourself. -- -- * Primary ID: id -- -- | Column name | Type | Description | -- |-|-|-| -- | id | integer (64) | You can document the user's ID field. | -- | firstName | string | The user's first name. | -- | active | boolean | Whether or not the user is able to log in. | --markdownTableRenderer :: Renderer Text