-- 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.2 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 (Data.StrMap.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.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.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 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 (a GHC.Types.~ ()) => 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. We'll use the -- mkEntityDefList function to expose it: -- --
-- share -- [ mkPersist sqlSettings -- , mkEntityDefList "entityDefs" -- ] [persistUpperCase| -- User -- firstName Text.Text -- active Bool -- deriving Show Eq Read Ord -- |] ---- -- You may want to factor out the quasiquoter into a term and import from -- another module. This has an important downside: the ID fields from the -- QuasiQuoter are given as Int64 regardless of what they -- actually are. It's not possible for the persistent quasiquoter to -- properly know the types of the IDs. -- --
-- docs :: [EntityDef] -- docs = document entityDefs $ do -- 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