{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

-- |
-- Module      : Docs.TextRevision
-- Description : A Revision of a Text Element
-- License     : AGPL-3
-- Maintainer  : stu235271@mail.uni-kiel.de
--               stu236925@mail.uni-kiel.de
--
-- This module contains definitions for revisions of @TextElement@s.
module Docs.TextRevision
    ( TextRevisionID (..)
    , TextRevisionSelector (..)
    , TextRevision (..)
    , TextRevisionHeader (..)
    , TextElementRevision (..)
    , ConflictStatus (..)
    , TextRevisionHistory (..)
    , NewTextRevision (..)
    , TextRevisionRef (..)
    , DraftRevisionID (..)
    , DraftRevision (..)
    , DraftRevisionHeader (..)
    , Rendered (..)
    , contentsNotChanged
    , prettyPrintTextRevisionRef
    , textRevisionRef
    , specificTextRevision
    , latestTextRevisionAsOf
    ) where

import Data.Proxy (Proxy (Proxy))
import Data.Scientific (toBoundedInteger)
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Time (UTCTime)
import qualified Data.Vector as Vector

import Text.Read (readMaybe)

import GHC.Generics (Generic)
import GHC.Int (Int64)

import Control.Lens ((&), (.~), (?~))
import Data.Aeson (FromJSON (..), ToJSON (..), (.:), (.=))
import qualified Data.Aeson as Aeson
import Data.Aeson.Types (Parser)
import qualified Data.HashMap.Strict.InsOrd as InsOrd
import Data.OpenApi
    ( HasFormat (format)
    , NamedSchema (..)
    , OpenApiType (..)
    , Referenced (Inline)
    , Schema (..)
    , ToParamSchema (..)
    , ToSchema (..)
    , declareSchemaRef
    , description
    , enum_
    , exclusiveMinimum
    , minimum_
    , oneOf
    , properties
    , required
    , type_
    )
import Web.HttpApiData (FromHttpApiData (..))

import Data.Vector (Vector)
import Docs.Comment (CommentAnchor)
import Docs.Document (DocumentID)
import Docs.TextElement
    ( TextElement
    , TextElementID
    , TextElementRef (..)
    , prettyPrintTextElementRef
    )
import Docs.UserRef (UserRef)
import Parse (parseFlexibleTime)

-- | A reference to a @TextRevision@
data TextRevisionRef
    = TextRevisionRef
        TextElementRef
        TextRevisionSelector
    deriving ((forall x. TextRevisionRef -> Rep TextRevisionRef x)
-> (forall x. Rep TextRevisionRef x -> TextRevisionRef)
-> Generic TextRevisionRef
forall x. Rep TextRevisionRef x -> TextRevisionRef
forall x. TextRevisionRef -> Rep TextRevisionRef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TextRevisionRef -> Rep TextRevisionRef x
from :: forall x. TextRevisionRef -> Rep TextRevisionRef x
$cto :: forall x. Rep TextRevisionRef x -> TextRevisionRef
to :: forall x. Rep TextRevisionRef x -> TextRevisionRef
Generic)

instance ToJSON TextRevisionRef

instance FromJSON TextRevisionRef

instance ToSchema TextRevisionRef

-- | Ein Schmackofatz für die Augen
prettyPrintTextRevisionRef :: TextRevisionRef -> String
prettyPrintTextRevisionRef :: TextRevisionRef -> String
prettyPrintTextRevisionRef (TextRevisionRef TextElementRef
textElementRef TextRevisionSelector
selector) =
    TextElementRef -> String
prettyPrintTextElementRef TextElementRef
textElementRef String -> String -> String
forall a. [a] -> [a] -> [a]
++ TextRevisionSelector -> String
prettyPrintSelector TextRevisionSelector
selector
  where
    prettyPrintSelector :: TextRevisionSelector -> String
prettyPrintSelector TextRevisionSelector
Latest = String
"latest"
    prettyPrintSelector (LatestAsOf UTCTime
ts) = UTCTime -> String
forall a. Show a => a -> String
show UTCTime
ts
    prettyPrintSelector (Specific TextRevisionID
revID) = Int64 -> String
forall a. Show a => a -> String
show (Int64 -> String) -> Int64 -> String
forall a b. (a -> b) -> a -> b
$ TextRevisionID -> Int64
unTextRevisionID TextRevisionID
revID

-- | Constructor for a @TextRevisionRef@
textRevisionRef
    :: DocumentID
    -> TextElementID
    -> TextRevisionSelector
    -> TextRevisionRef
textRevisionRef :: DocumentID
-> TextElementID -> TextRevisionSelector -> TextRevisionRef
textRevisionRef = (TextElementRef -> TextRevisionSelector -> TextRevisionRef
TextRevisionRef (TextElementRef -> TextRevisionSelector -> TextRevisionRef)
-> (TextElementID -> TextElementRef)
-> TextElementID
-> TextRevisionSelector
-> TextRevisionRef
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextElementID -> TextElementRef)
 -> TextElementID -> TextRevisionSelector -> TextRevisionRef)
-> (DocumentID -> TextElementID -> TextElementRef)
-> DocumentID
-> TextElementID
-> TextRevisionSelector
-> TextRevisionRef
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> TextElementID -> TextElementRef
TextElementRef

-- | ID for a text revision
newtype TextRevisionID = TextRevisionID
    { TextRevisionID -> Int64
unTextRevisionID :: Int64
    }
    deriving (TextRevisionID -> TextRevisionID -> Bool
(TextRevisionID -> TextRevisionID -> Bool)
-> (TextRevisionID -> TextRevisionID -> Bool) -> Eq TextRevisionID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TextRevisionID -> TextRevisionID -> Bool
== :: TextRevisionID -> TextRevisionID -> Bool
$c/= :: TextRevisionID -> TextRevisionID -> Bool
/= :: TextRevisionID -> TextRevisionID -> Bool
Eq, Eq TextRevisionID
Eq TextRevisionID =>
(TextRevisionID -> TextRevisionID -> Ordering)
-> (TextRevisionID -> TextRevisionID -> Bool)
-> (TextRevisionID -> TextRevisionID -> Bool)
-> (TextRevisionID -> TextRevisionID -> Bool)
-> (TextRevisionID -> TextRevisionID -> Bool)
-> (TextRevisionID -> TextRevisionID -> TextRevisionID)
-> (TextRevisionID -> TextRevisionID -> TextRevisionID)
-> Ord TextRevisionID
TextRevisionID -> TextRevisionID -> Bool
TextRevisionID -> TextRevisionID -> Ordering
TextRevisionID -> TextRevisionID -> TextRevisionID
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
$ccompare :: TextRevisionID -> TextRevisionID -> Ordering
compare :: TextRevisionID -> TextRevisionID -> Ordering
$c< :: TextRevisionID -> TextRevisionID -> Bool
< :: TextRevisionID -> TextRevisionID -> Bool
$c<= :: TextRevisionID -> TextRevisionID -> Bool
<= :: TextRevisionID -> TextRevisionID -> Bool
$c> :: TextRevisionID -> TextRevisionID -> Bool
> :: TextRevisionID -> TextRevisionID -> Bool
$c>= :: TextRevisionID -> TextRevisionID -> Bool
>= :: TextRevisionID -> TextRevisionID -> Bool
$cmax :: TextRevisionID -> TextRevisionID -> TextRevisionID
max :: TextRevisionID -> TextRevisionID -> TextRevisionID
$cmin :: TextRevisionID -> TextRevisionID -> TextRevisionID
min :: TextRevisionID -> TextRevisionID -> TextRevisionID
Ord, Int -> TextRevisionID -> String -> String
[TextRevisionID] -> String -> String
TextRevisionID -> String
(Int -> TextRevisionID -> String -> String)
-> (TextRevisionID -> String)
-> ([TextRevisionID] -> String -> String)
-> Show TextRevisionID
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> TextRevisionID -> String -> String
showsPrec :: Int -> TextRevisionID -> String -> String
$cshow :: TextRevisionID -> String
show :: TextRevisionID -> String
$cshowList :: [TextRevisionID] -> String -> String
showList :: [TextRevisionID] -> String -> String
Show)

instance ToJSON TextRevisionID where
    toJSON :: TextRevisionID -> Value
toJSON = Int64 -> Value
forall a. ToJSON a => a -> Value
toJSON (Int64 -> Value)
-> (TextRevisionID -> Int64) -> TextRevisionID -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextRevisionID -> Int64
unTextRevisionID

instance FromJSON TextRevisionID where
    parseJSON :: Value -> Parser TextRevisionID
parseJSON = (Int64 -> TextRevisionID) -> Parser Int64 -> Parser TextRevisionID
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int64 -> TextRevisionID
TextRevisionID (Parser Int64 -> Parser TextRevisionID)
-> (Value -> Parser Int64) -> Value -> Parser TextRevisionID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser Int64
forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToSchema TextRevisionID where
    declareNamedSchema :: Proxy TextRevisionID -> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy TextRevisionID
_ = Proxy Int64 -> Declare (Definitions Schema) NamedSchema
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) NamedSchema
declareNamedSchema (Proxy Int64
forall {k} (t :: k). Proxy t
Proxy :: Proxy Int64)

instance ToParamSchema TextRevisionID where
    toParamSchema :: Proxy TextRevisionID -> Schema
toParamSchema Proxy TextRevisionID
_ =
        Schema
forall a. Monoid a => a
mempty
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiInteger
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Scientific -> Identity (Maybe Scientific))
-> Schema -> Identity Schema
forall s a. HasMinimum s a => Lens' s a
Lens' Schema (Maybe Scientific)
minimum_ ((Maybe Scientific -> Identity (Maybe Scientific))
 -> Schema -> Identity Schema)
-> Scientific -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Scientific
0
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Bool -> Identity (Maybe Bool)) -> Schema -> Identity Schema
forall s a. HasExclusiveMinimum s a => Lens' s a
Lens' Schema (Maybe Bool)
exclusiveMinimum ((Maybe Bool -> Identity (Maybe Bool))
 -> Schema -> Identity Schema)
-> Bool -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Bool
False

instance FromHttpApiData TextRevisionID where
    parseUrlPiece :: Text -> Either Text TextRevisionID
parseUrlPiece = (Int64 -> TextRevisionID
TextRevisionID (Int64 -> TextRevisionID)
-> Either Text Int64 -> Either Text TextRevisionID
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Either Text Int64 -> Either Text TextRevisionID)
-> (Text -> Either Text Int64)
-> Text
-> Either Text TextRevisionID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Int64
forall a. FromHttpApiData a => Text -> Either Text a
parseUrlPiece

-- | Selector for a text revision
data TextRevisionSelector
    = Latest
    | LatestAsOf UTCTime
    | Specific TextRevisionID

instance ToJSON TextRevisionSelector where
    toJSON :: TextRevisionSelector -> Value
toJSON TextRevisionSelector
Latest = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text
"latest" :: Text)
    toJSON (LatestAsOf UTCTime
ts) = UTCTime -> Value
forall a. ToJSON a => a -> Value
toJSON UTCTime
ts
    toJSON (Specific TextRevisionID
id_) = TextRevisionID -> Value
forall a. ToJSON a => a -> Value
toJSON TextRevisionID
id_

instance FromJSON TextRevisionSelector where
    parseJSON :: Value -> Parser TextRevisionSelector
parseJSON Value
v = case Value
v of
        Aeson.String Text
"latest" -> TextRevisionSelector -> Parser TextRevisionSelector
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TextRevisionSelector
Latest
        Aeson.String Text
_ -> UTCTime -> TextRevisionSelector
LatestAsOf (UTCTime -> TextRevisionSelector)
-> Parser UTCTime -> Parser TextRevisionSelector
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser UTCTime
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v -- TODO: parseFlexibleTime?
        Aeson.Number Scientific
n -> case Scientific -> Maybe Int64
forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger Scientific
n of
            Just Int64
i -> TextRevisionSelector -> Parser TextRevisionSelector
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TextRevisionSelector -> Parser TextRevisionSelector)
-> TextRevisionSelector -> Parser TextRevisionSelector
forall a b. (a -> b) -> a -> b
$ TextRevisionID -> TextRevisionSelector
Specific (TextRevisionID -> TextRevisionSelector)
-> TextRevisionID -> TextRevisionSelector
forall a b. (a -> b) -> a -> b
$ Int64 -> TextRevisionID
TextRevisionID Int64
i
            Maybe Int64
Nothing -> String -> Parser TextRevisionSelector
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid number for Int64"
        Value
_ -> String -> Parser TextRevisionSelector
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"TextRevisionSelector must be either a string \"latest\" or an integer"

instance ToSchema TextRevisionSelector where
    declareNamedSchema :: Proxy TextRevisionSelector
-> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy TextRevisionSelector
_ = do
        Referenced Schema
intSchema <- Proxy Int64 -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy Int64
forall {k} (t :: k). Proxy t
Proxy :: Proxy Int64)
        Referenced Schema
timestampSchema <- Proxy UTCTime -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy UTCTime
forall {k} (t :: k). Proxy t
Proxy :: Proxy UTCTime)
        let latestSchema :: Referenced Schema
latestSchema =
                Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                    Schema
forall a. Monoid a => a
mempty
                        Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiString
                        Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe [Value] -> Identity (Maybe [Value]))
-> Schema -> Identity Schema
forall s a. HasEnum s a => Lens' s a
Lens' Schema (Maybe [Value])
enum_ ((Maybe [Value] -> Identity (Maybe [Value]))
 -> Schema -> Identity Schema)
-> [Value] -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [Value
"latest"]
        NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a. a -> DeclareT (Definitions Schema) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (NamedSchema -> Declare (Definitions Schema) NamedSchema)
-> NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> Schema -> NamedSchema
NamedSchema (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"TextRevisionSelector") (Schema -> NamedSchema) -> Schema -> NamedSchema
forall a b. (a -> b) -> a -> b
$
                Schema
forall a. Monoid a => a
mempty Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe [Referenced Schema] -> Identity (Maybe [Referenced Schema]))
-> Schema -> Identity Schema
forall s a. HasOneOf s a => Lens' s a
Lens' Schema (Maybe [Referenced Schema])
oneOf ((Maybe [Referenced Schema]
  -> Identity (Maybe [Referenced Schema]))
 -> Schema -> Identity Schema)
-> [Referenced Schema] -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [Referenced Schema
latestSchema, Referenced Schema
intSchema, Referenced Schema
timestampSchema]

instance ToParamSchema TextRevisionSelector where
    toParamSchema :: Proxy TextRevisionSelector -> Schema
toParamSchema Proxy TextRevisionSelector
_ =
        Schema
forall a. Monoid a => a
mempty
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe [Referenced Schema] -> Identity (Maybe [Referenced Schema]))
-> Schema -> Identity Schema
forall s a. HasOneOf s a => Lens' s a
Lens' Schema (Maybe [Referenced Schema])
oneOf
                ((Maybe [Referenced Schema]
  -> Identity (Maybe [Referenced Schema]))
 -> Schema -> Identity Schema)
-> [Referenced Schema] -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [ Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                        Schema
forall a. Monoid a => a
mempty
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiString
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe [Value] -> Identity (Maybe [Value]))
-> Schema -> Identity Schema
forall s a. HasEnum s a => Lens' s a
Lens' Schema (Maybe [Value])
enum_ ((Maybe [Value] -> Identity (Maybe [Value]))
 -> Schema -> Identity Schema)
-> [Value] -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [Value
"latest"]
                   , Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                        Schema
forall a. Monoid a => a
mempty
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiString
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text)) -> Schema -> Identity Schema
forall s a. HasFormat s a => Lens' s a
Lens' Schema (Maybe Text)
format ((Maybe Text -> Identity (Maybe Text))
 -> Schema -> Identity Schema)
-> Text -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"date-time"
                   , Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                        Schema
forall a. Monoid a => a
mempty
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiInteger
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Scientific -> Identity (Maybe Scientific))
-> Schema -> Identity Schema
forall s a. HasMinimum s a => Lens' s a
Lens' Schema (Maybe Scientific)
minimum_ ((Maybe Scientific -> Identity (Maybe Scientific))
 -> Schema -> Identity Schema)
-> Scientific -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Scientific
0
                            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Bool -> Identity (Maybe Bool)) -> Schema -> Identity Schema
forall s a. HasExclusiveMinimum s a => Lens' s a
Lens' Schema (Maybe Bool)
exclusiveMinimum ((Maybe Bool -> Identity (Maybe Bool))
 -> Schema -> Identity Schema)
-> Bool -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Bool
False
                   ]

instance FromHttpApiData TextRevisionSelector where
    parseUrlPiece :: Text -> Either Text TextRevisionSelector
parseUrlPiece Text
txt
        | Text -> Text
Text.toLower Text
txt Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"latest" = TextRevisionSelector -> Either Text TextRevisionSelector
forall a b. b -> Either a b
Right TextRevisionSelector
Latest
        | Bool
otherwise =
            case String -> Maybe Int64
forall a. Read a => String -> Maybe a
readMaybe (Text -> String
Text.unpack Text
txt) of
                Just Int64
i -> TextRevisionSelector -> Either Text TextRevisionSelector
forall a b. b -> Either a b
Right (TextRevisionSelector -> Either Text TextRevisionSelector)
-> TextRevisionSelector -> Either Text TextRevisionSelector
forall a b. (a -> b) -> a -> b
$ TextRevisionID -> TextRevisionSelector
Specific (TextRevisionID -> TextRevisionSelector)
-> TextRevisionID -> TextRevisionSelector
forall a b. (a -> b) -> a -> b
$ Int64 -> TextRevisionID
TextRevisionID Int64
i
                Maybe Int64
Nothing ->
                    case String -> Maybe UTCTime
parseFlexibleTime (Text -> String
Text.unpack Text
txt) of
                        Just UTCTime
ts -> TextRevisionSelector -> Either Text TextRevisionSelector
forall a b. b -> Either a b
Right (TextRevisionSelector -> Either Text TextRevisionSelector)
-> TextRevisionSelector -> Either Text TextRevisionSelector
forall a b. (a -> b) -> a -> b
$ UTCTime -> TextRevisionSelector
LatestAsOf UTCTime
ts
                        Maybe UTCTime
Nothing -> Text -> Either Text TextRevisionSelector
forall a b. a -> Either a b
Left (Text -> Either Text TextRevisionSelector)
-> Text -> Either Text TextRevisionSelector
forall a b. (a -> b) -> a -> b
$ Text
"Invalid TextRevisionSelector: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
txt

specificTextRevision :: TextRevisionSelector -> Maybe TextRevisionID
specificTextRevision :: TextRevisionSelector -> Maybe TextRevisionID
specificTextRevision (Specific TextRevisionID
id_) = TextRevisionID -> Maybe TextRevisionID
forall a. a -> Maybe a
Just TextRevisionID
id_
specificTextRevision TextRevisionSelector
_ = Maybe TextRevisionID
forall a. Maybe a
Nothing

latestTextRevisionAsOf :: TextRevisionSelector -> Maybe UTCTime
latestTextRevisionAsOf :: TextRevisionSelector -> Maybe UTCTime
latestTextRevisionAsOf (LatestAsOf UTCTime
ts) = UTCTime -> Maybe UTCTime
forall a. a -> Maybe a
Just UTCTime
ts
latestTextRevisionAsOf TextRevisionSelector
_ = Maybe UTCTime
forall a. Maybe a
Nothing

-- | Header of a text revision.
--   Contains metadata for a text revision.
data TextRevisionHeader = TextRevisionHeader
    { TextRevisionHeader -> TextRevisionID
identifier :: TextRevisionID
    -- ^ the id of the revision
    , TextRevisionHeader -> UTCTime
timestamp :: UTCTime
    -- ^ the creation timestamp of the revision
    , TextRevisionHeader -> UserRef
author :: UserRef
    -- ^ the user who created the revision
    }
    deriving (Int -> TextRevisionHeader -> String -> String
[TextRevisionHeader] -> String -> String
TextRevisionHeader -> String
(Int -> TextRevisionHeader -> String -> String)
-> (TextRevisionHeader -> String)
-> ([TextRevisionHeader] -> String -> String)
-> Show TextRevisionHeader
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> TextRevisionHeader -> String -> String
showsPrec :: Int -> TextRevisionHeader -> String -> String
$cshow :: TextRevisionHeader -> String
show :: TextRevisionHeader -> String
$cshowList :: [TextRevisionHeader] -> String -> String
showList :: [TextRevisionHeader] -> String -> String
Show, (forall x. TextRevisionHeader -> Rep TextRevisionHeader x)
-> (forall x. Rep TextRevisionHeader x -> TextRevisionHeader)
-> Generic TextRevisionHeader
forall x. Rep TextRevisionHeader x -> TextRevisionHeader
forall x. TextRevisionHeader -> Rep TextRevisionHeader x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TextRevisionHeader -> Rep TextRevisionHeader x
from :: forall x. TextRevisionHeader -> Rep TextRevisionHeader x
$cto :: forall x. Rep TextRevisionHeader x -> TextRevisionHeader
to :: forall x. Rep TextRevisionHeader x -> TextRevisionHeader
Generic)

instance ToJSON TextRevisionHeader

instance FromJSON TextRevisionHeader

instance ToSchema TextRevisionHeader

-- | A text revision.
data TextRevision = TextRevision
    { TextRevision -> TextRevisionHeader
header :: TextRevisionHeader
    -- ^ meta data about the revision
    , TextRevision -> Text
content :: Text
    -- ^ the content of the revision
    , TextRevision -> Vector CommentAnchor
commentAnchors :: Vector CommentAnchor
    -- ^ anchors for comments in the revisions text
    }
    deriving ((forall x. TextRevision -> Rep TextRevision x)
-> (forall x. Rep TextRevision x -> TextRevision)
-> Generic TextRevision
forall x. Rep TextRevision x -> TextRevision
forall x. TextRevision -> Rep TextRevision x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TextRevision -> Rep TextRevision x
from :: forall x. TextRevision -> Rep TextRevision x
$cto :: forall x. Rep TextRevision x -> TextRevision
to :: forall x. Rep TextRevision x -> TextRevision
Generic)

instance ToJSON TextRevision

instance FromJSON TextRevision

instance ToSchema TextRevision

-- | A text revision with the text element it belongs to.
data TextElementRevision = TextElementRevision
    { TextElementRevision -> TextElement
textElement :: TextElement
    , TextElementRevision -> Maybe TextRevision
revision :: Maybe TextRevision
    }
    deriving ((forall x. TextElementRevision -> Rep TextElementRevision x)
-> (forall x. Rep TextElementRevision x -> TextElementRevision)
-> Generic TextElementRevision
forall x. Rep TextElementRevision x -> TextElementRevision
forall x. TextElementRevision -> Rep TextElementRevision x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TextElementRevision -> Rep TextElementRevision x
from :: forall x. TextElementRevision -> Rep TextElementRevision x
$cto :: forall x. Rep TextElementRevision x -> TextElementRevision
to :: forall x. Rep TextElementRevision x -> TextElementRevision
Generic)

instance ToJSON TextElementRevision

instance FromJSON TextElementRevision

instance ToSchema TextElementRevision

-- | ID for a draft text revision
newtype DraftRevisionID = DraftRevisionID
    { DraftRevisionID -> Int64
unDraftRevisionID :: Int64
    }
    deriving (DraftRevisionID -> DraftRevisionID -> Bool
(DraftRevisionID -> DraftRevisionID -> Bool)
-> (DraftRevisionID -> DraftRevisionID -> Bool)
-> Eq DraftRevisionID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DraftRevisionID -> DraftRevisionID -> Bool
== :: DraftRevisionID -> DraftRevisionID -> Bool
$c/= :: DraftRevisionID -> DraftRevisionID -> Bool
/= :: DraftRevisionID -> DraftRevisionID -> Bool
Eq, Eq DraftRevisionID
Eq DraftRevisionID =>
(DraftRevisionID -> DraftRevisionID -> Ordering)
-> (DraftRevisionID -> DraftRevisionID -> Bool)
-> (DraftRevisionID -> DraftRevisionID -> Bool)
-> (DraftRevisionID -> DraftRevisionID -> Bool)
-> (DraftRevisionID -> DraftRevisionID -> Bool)
-> (DraftRevisionID -> DraftRevisionID -> DraftRevisionID)
-> (DraftRevisionID -> DraftRevisionID -> DraftRevisionID)
-> Ord DraftRevisionID
DraftRevisionID -> DraftRevisionID -> Bool
DraftRevisionID -> DraftRevisionID -> Ordering
DraftRevisionID -> DraftRevisionID -> DraftRevisionID
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
$ccompare :: DraftRevisionID -> DraftRevisionID -> Ordering
compare :: DraftRevisionID -> DraftRevisionID -> Ordering
$c< :: DraftRevisionID -> DraftRevisionID -> Bool
< :: DraftRevisionID -> DraftRevisionID -> Bool
$c<= :: DraftRevisionID -> DraftRevisionID -> Bool
<= :: DraftRevisionID -> DraftRevisionID -> Bool
$c> :: DraftRevisionID -> DraftRevisionID -> Bool
> :: DraftRevisionID -> DraftRevisionID -> Bool
$c>= :: DraftRevisionID -> DraftRevisionID -> Bool
>= :: DraftRevisionID -> DraftRevisionID -> Bool
$cmax :: DraftRevisionID -> DraftRevisionID -> DraftRevisionID
max :: DraftRevisionID -> DraftRevisionID -> DraftRevisionID
$cmin :: DraftRevisionID -> DraftRevisionID -> DraftRevisionID
min :: DraftRevisionID -> DraftRevisionID -> DraftRevisionID
Ord, Int -> DraftRevisionID -> String -> String
[DraftRevisionID] -> String -> String
DraftRevisionID -> String
(Int -> DraftRevisionID -> String -> String)
-> (DraftRevisionID -> String)
-> ([DraftRevisionID] -> String -> String)
-> Show DraftRevisionID
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> DraftRevisionID -> String -> String
showsPrec :: Int -> DraftRevisionID -> String -> String
$cshow :: DraftRevisionID -> String
show :: DraftRevisionID -> String
$cshowList :: [DraftRevisionID] -> String -> String
showList :: [DraftRevisionID] -> String -> String
Show)

instance ToJSON DraftRevisionID where
    toJSON :: DraftRevisionID -> Value
toJSON = Int64 -> Value
forall a. ToJSON a => a -> Value
toJSON (Int64 -> Value)
-> (DraftRevisionID -> Int64) -> DraftRevisionID -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DraftRevisionID -> Int64
unDraftRevisionID

instance FromJSON DraftRevisionID where
    parseJSON :: Value -> Parser DraftRevisionID
parseJSON = (Int64 -> DraftRevisionID)
-> Parser Int64 -> Parser DraftRevisionID
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int64 -> DraftRevisionID
DraftRevisionID (Parser Int64 -> Parser DraftRevisionID)
-> (Value -> Parser Int64) -> Value -> Parser DraftRevisionID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser Int64
forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToSchema DraftRevisionID where
    declareNamedSchema :: Proxy DraftRevisionID -> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy DraftRevisionID
_ = Proxy Int64 -> Declare (Definitions Schema) NamedSchema
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) NamedSchema
declareNamedSchema (Proxy Int64
forall {k} (t :: k). Proxy t
Proxy :: Proxy Int64)

-- | Header of a draft text revision.
data DraftRevisionHeader = DraftRevisionHeader
    { DraftRevisionHeader -> DraftRevisionID
draftIdentifier :: DraftRevisionID
    , DraftRevisionHeader -> TextRevisionID
basedOnRevision :: TextRevisionID
    , DraftRevisionHeader -> UTCTime
creationTimestamp :: UTCTime
    , DraftRevisionHeader -> UTCTime
lastUpdatedTimestamp :: UTCTime
    , DraftRevisionHeader -> UserRef
draftAuthor :: UserRef
    }
    deriving (Int -> DraftRevisionHeader -> String -> String
[DraftRevisionHeader] -> String -> String
DraftRevisionHeader -> String
(Int -> DraftRevisionHeader -> String -> String)
-> (DraftRevisionHeader -> String)
-> ([DraftRevisionHeader] -> String -> String)
-> Show DraftRevisionHeader
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> DraftRevisionHeader -> String -> String
showsPrec :: Int -> DraftRevisionHeader -> String -> String
$cshow :: DraftRevisionHeader -> String
show :: DraftRevisionHeader -> String
$cshowList :: [DraftRevisionHeader] -> String -> String
showList :: [DraftRevisionHeader] -> String -> String
Show, (forall x. DraftRevisionHeader -> Rep DraftRevisionHeader x)
-> (forall x. Rep DraftRevisionHeader x -> DraftRevisionHeader)
-> Generic DraftRevisionHeader
forall x. Rep DraftRevisionHeader x -> DraftRevisionHeader
forall x. DraftRevisionHeader -> Rep DraftRevisionHeader x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DraftRevisionHeader -> Rep DraftRevisionHeader x
from :: forall x. DraftRevisionHeader -> Rep DraftRevisionHeader x
$cto :: forall x. Rep DraftRevisionHeader x -> DraftRevisionHeader
to :: forall x. Rep DraftRevisionHeader x -> DraftRevisionHeader
Generic)

instance ToJSON DraftRevisionHeader

instance FromJSON DraftRevisionHeader

instance ToSchema DraftRevisionHeader

-- | A draft text revision.
data DraftRevision = DraftRevision
    { DraftRevision -> DraftRevisionHeader
draftHeader :: DraftRevisionHeader
    , DraftRevision -> Text
draftContent :: Text
    , DraftRevision -> Vector CommentAnchor
draftCommentAnchors :: Vector CommentAnchor
    }
    deriving ((forall x. DraftRevision -> Rep DraftRevision x)
-> (forall x. Rep DraftRevision x -> DraftRevision)
-> Generic DraftRevision
forall x. Rep DraftRevision x -> DraftRevision
forall x. DraftRevision -> Rep DraftRevision x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DraftRevision -> Rep DraftRevision x
from :: forall x. DraftRevision -> Rep DraftRevision x
$cto :: forall x. Rep DraftRevision x -> DraftRevision
to :: forall x. Rep DraftRevision x -> DraftRevision
Generic)

instance ToJSON DraftRevision

instance FromJSON DraftRevision

instance ToSchema DraftRevision

-- | A sequence of revisions for a text element
data TextRevisionHistory
    = TextRevisionHistory
        TextElementRef
        [TextRevisionHeader]

instance ToJSON TextRevisionHistory where
    toJSON :: TextRevisionHistory -> Value
toJSON (TextRevisionHistory TextElementRef
elementRef [TextRevisionHeader]
history) =
        [Pair] -> Value
Aeson.object [Key
"textElement" Key -> TextElementRef -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= TextElementRef
elementRef, Key
"history" Key -> [TextRevisionHeader] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [TextRevisionHeader]
history]

instance FromJSON TextRevisionHistory where
    parseJSON :: Value -> Parser TextRevisionHistory
parseJSON = String
-> (Object -> Parser TextRevisionHistory)
-> Value
-> Parser TextRevisionHistory
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"TextRevisionHistory" ((Object -> Parser TextRevisionHistory)
 -> Value -> Parser TextRevisionHistory)
-> (Object -> Parser TextRevisionHistory)
-> Value
-> Parser TextRevisionHistory
forall a b. (a -> b) -> a -> b
$ \Object
v ->
        TextElementRef -> [TextRevisionHeader] -> TextRevisionHistory
TextRevisionHistory
            (TextElementRef -> [TextRevisionHeader] -> TextRevisionHistory)
-> Parser TextElementRef
-> Parser ([TextRevisionHeader] -> TextRevisionHistory)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser TextElementRef
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"textElement"
            Parser ([TextRevisionHeader] -> TextRevisionHistory)
-> Parser [TextRevisionHeader] -> Parser TextRevisionHistory
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser [TextRevisionHeader]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"history"

instance ToSchema TextRevisionHistory where
    declareNamedSchema :: Proxy TextRevisionHistory
-> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy TextRevisionHistory
_ = do
        Referenced Schema
textElementSchema <- Proxy TextElementRef
-> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy TextElementRef
forall {k} (t :: k). Proxy t
Proxy :: Proxy TextElementRef)
        Referenced Schema
historySchema <- Proxy [TextRevisionHeader]
-> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy [TextRevisionHeader]
forall {k} (t :: k). Proxy t
Proxy :: Proxy [TextRevisionHeader])
        NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a. a -> DeclareT (Definitions Schema) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (NamedSchema -> Declare (Definitions Schema) NamedSchema)
-> NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> Schema -> NamedSchema
NamedSchema (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"TextRevisionHistory") (Schema -> NamedSchema) -> Schema -> NamedSchema
forall a b. (a -> b) -> a -> b
$
                Schema
forall a. Monoid a => a
mempty
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> Schema -> Identity Schema
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
                        ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> Schema -> Identity Schema)
-> InsOrdHashMap Text (Referenced Schema) -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [(Text, Referenced Schema)]
-> InsOrdHashMap Text (Referenced Schema)
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
InsOrd.fromList
                            [ (Text
"textElement", Referenced Schema
textElementSchema)
                            , (Text
"history", Referenced Schema
historySchema)
                            ]
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& ([Text] -> Identity [Text]) -> Schema -> Identity Schema
forall s a. HasRequired s a => Lens' s a
Lens' Schema [Text]
required (([Text] -> Identity [Text]) -> Schema -> Identity Schema)
-> [Text] -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [Text
"textElement", Text
"history"]

-- | Information required to create a new text revision.
data NewTextRevision = NewTextRevision
    { NewTextRevision -> TextElementRef
newTextRevisionElement :: TextElementRef
    , NewTextRevision -> Maybe TextRevisionID
newTextRevisionParent :: Maybe TextRevisionID
    , NewTextRevision -> Text
newTextRevisionContent :: Text
    , NewTextRevision -> Vector CommentAnchor
newTextRevisionCommentAnchors :: Vector CommentAnchor
    , NewTextRevision -> Bool
newTextRevisionIsAutoSave :: Bool
    }

-- | Check if a new revisions contents changed from an existing one.
contentsNotChanged :: TextRevision -> NewTextRevision -> Bool
contentsNotChanged :: TextRevision -> NewTextRevision -> Bool
contentsNotChanged TextRevision
latest NewTextRevision
newRevision =
    TextRevision -> Text
content TextRevision
latest Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== NewTextRevision -> Text
newTextRevisionContent NewTextRevision
newRevision
        Bool -> Bool -> Bool
&& TextRevision -> Vector CommentAnchor
commentAnchors TextRevision
latest Vector CommentAnchor -> Vector CommentAnchor -> Bool
forall {a}. Ord a => Vector a -> Vector a -> Bool
`eqAsSet` NewTextRevision -> Vector CommentAnchor
newTextRevisionCommentAnchors NewTextRevision
newRevision
  where
    eqAsSet :: Vector a -> Vector a -> Bool
eqAsSet Vector a
a Vector a
b =
        [a] -> Set a
forall a. Ord a => [a] -> Set a
Set.fromList (Vector a -> [a]
forall a. Vector a -> [a]
Vector.toList Vector a
a) Set a -> Set a -> Bool
forall a. Eq a => a -> a -> Bool
== [a] -> Set a
forall a. Ord a => [a] -> Set a
Set.fromList (Vector a -> [a]
forall a. Vector a -> [a]
Vector.toList Vector a
b)

-- | A conflict with another text revision.
data ConflictStatus
    = Conflict TextRevisionID -- todo: maybe not id but whole TextRevision?
    | NoConflict TextRevision
    | -- | created draft and conflicting revision ID
      DraftCreated DraftRevision TextRevisionID

instance ToJSON ConflictStatus where
    toJSON :: ConflictStatus -> Value
toJSON (Conflict TextRevisionID
conflictWith) =
        [Pair] -> Value
Aeson.object [Key
"type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"conflict" :: Text), Key
"with" Key -> TextRevisionID -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= TextRevisionID
conflictWith]
    toJSON (NoConflict TextRevision
newRevision) =
        [Pair] -> Value
Aeson.object [Key
"type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"noConflict" :: Text), Key
"newRevision" Key -> TextRevision -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= TextRevision
newRevision]
    toJSON (DraftCreated DraftRevision
draftRevision TextRevisionID
conflictWith) =
        [Pair] -> Value
Aeson.object
            [ Key
"type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"draftCreated" :: Text)
            , Key
"draft" Key -> DraftRevision -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DraftRevision
draftRevision
            , Key
"with" Key -> TextRevisionID -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= TextRevisionID
conflictWith
            ]

instance FromJSON ConflictStatus where
    parseJSON :: Value -> Parser ConflictStatus
parseJSON = String
-> (Object -> Parser ConflictStatus)
-> Value
-> Parser ConflictStatus
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"ConflictStatus" ((Object -> Parser ConflictStatus)
 -> Value -> Parser ConflictStatus)
-> (Object -> Parser ConflictStatus)
-> Value
-> Parser ConflictStatus
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
        Text
ty <- Object
obj Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Text
        case Text
ty of
            Text
"conflict" -> TextRevisionID -> ConflictStatus
Conflict (TextRevisionID -> ConflictStatus)
-> Parser TextRevisionID -> Parser ConflictStatus
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Key -> Parser TextRevisionID
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"with"
            Text
"noConflict" -> TextRevision -> ConflictStatus
NoConflict (TextRevision -> ConflictStatus)
-> Parser TextRevision -> Parser ConflictStatus
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Key -> Parser TextRevision
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"newRevision"
            Text
"draftCreated" -> DraftRevision -> TextRevisionID -> ConflictStatus
DraftCreated (DraftRevision -> TextRevisionID -> ConflictStatus)
-> Parser DraftRevision
-> Parser (TextRevisionID -> ConflictStatus)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Key -> Parser DraftRevision
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"draft" Parser (TextRevisionID -> ConflictStatus)
-> Parser TextRevisionID -> Parser ConflictStatus
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
obj Object -> Key -> Parser TextRevisionID
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"with"
            Text
_ -> String -> Parser ConflictStatus
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ConflictStatus)
-> String -> Parser ConflictStatus
forall a b. (a -> b) -> a -> b
$ String
"Unknown ConflictStatus type: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show Text
ty

instance ToSchema ConflictStatus where
    declareNamedSchema :: Proxy ConflictStatus -> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy ConflictStatus
_ = do
        Referenced Schema
textRevIdSchema <- Proxy TextRevisionID
-> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy TextRevisionID
forall {k} (t :: k). Proxy t
Proxy :: Proxy TextRevisionID)
        Referenced Schema
textRevSchema <- Proxy TextRevision
-> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy TextRevision
forall {k} (t :: k). Proxy t
Proxy :: Proxy TextRevision)
        Referenced Schema
draftRevSchema <- Proxy DraftRevision
-> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy DraftRevision
forall {k} (t :: k). Proxy t
Proxy :: Proxy DraftRevision)

        NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a. a -> DeclareT (Definitions Schema) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (NamedSchema -> Declare (Definitions Schema) NamedSchema)
-> NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> Schema -> NamedSchema
NamedSchema (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"ConflictStatus") (Schema -> NamedSchema) -> Schema -> NamedSchema
forall a b. (a -> b) -> a -> b
$
                Schema
forall a. Monoid a => a
mempty
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text)) -> Schema -> Identity Schema
forall s a. HasDescription s a => Lens' s a
Lens' Schema (Maybe Text)
description
                        ((Maybe Text -> Identity (Maybe Text))
 -> Schema -> Identity Schema)
-> Text -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"Status of text revision creation - can be no conflict, conflict with existing revision, or draft created due to AutoSave conflict"
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe [Referenced Schema] -> Identity (Maybe [Referenced Schema]))
-> Schema -> Identity Schema
forall s a. HasOneOf s a => Lens' s a
Lens' Schema (Maybe [Referenced Schema])
oneOf
                        ((Maybe [Referenced Schema]
  -> Identity (Maybe [Referenced Schema]))
 -> Schema -> Identity Schema)
-> [Referenced Schema] -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [ Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                                Schema
forall a. Monoid a => a
mempty
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> Schema -> Identity Schema
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
                                        ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> Schema -> Identity Schema)
-> InsOrdHashMap Text (Referenced Schema) -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [(Text, Referenced Schema)]
-> InsOrdHashMap Text (Referenced Schema)
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
InsOrd.fromList
                                            [ (Text
"type", Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$ Text -> Schema
schemaConstText Text
"conflict")
                                            , (Text
"with", Referenced Schema
textRevIdSchema)
                                            ]
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& ([Text] -> Identity [Text]) -> Schema -> Identity Schema
forall s a. HasRequired s a => Lens' s a
Lens' Schema [Text]
required (([Text] -> Identity [Text]) -> Schema -> Identity Schema)
-> [Text] -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [Text
"type", Text
"with"]
                           , Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                                Schema
forall a. Monoid a => a
mempty
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> Schema -> Identity Schema
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
                                        ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> Schema -> Identity Schema)
-> InsOrdHashMap Text (Referenced Schema) -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [(Text, Referenced Schema)]
-> InsOrdHashMap Text (Referenced Schema)
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
InsOrd.fromList
                                            [ (Text
"type", Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$ Text -> Schema
schemaConstText Text
"noConflict")
                                            , (Text
"newRevision", Referenced Schema
textRevSchema)
                                            ]
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& ([Text] -> Identity [Text]) -> Schema -> Identity Schema
forall s a. HasRequired s a => Lens' s a
Lens' Schema [Text]
required (([Text] -> Identity [Text]) -> Schema -> Identity Schema)
-> [Text] -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [Text
"type", Text
"newRevision"]
                           , Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$
                                Schema
forall a. Monoid a => a
mempty
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> Schema -> Identity Schema
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
                                        ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> Schema -> Identity Schema)
-> InsOrdHashMap Text (Referenced Schema) -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [(Text, Referenced Schema)]
-> InsOrdHashMap Text (Referenced Schema)
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
InsOrd.fromList
                                            [ (Text
"type", Schema -> Referenced Schema
forall a. a -> Referenced a
Inline (Schema -> Referenced Schema) -> Schema -> Referenced Schema
forall a b. (a -> b) -> a -> b
$ Text -> Schema
schemaConstText Text
"draftCreated")
                                            , (Text
"draft", Referenced Schema
draftRevSchema)
                                            , (Text
"with", Referenced Schema
textRevIdSchema)
                                            ]
                                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& ([Text] -> Identity [Text]) -> Schema -> Identity Schema
forall s a. HasRequired s a => Lens' s a
Lens' Schema [Text]
required (([Text] -> Identity [Text]) -> Schema -> Identity Schema)
-> [Text] -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [Text
"type", Text
"draft", Text
"with"]
                           ]
      where
        schemaConstText :: Text -> Schema
        schemaConstText :: Text -> Schema
schemaConstText Text
val =
            Schema
forall a. Monoid a => a
mempty
                Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiString
                Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe [Value] -> Identity (Maybe [Value]))
-> Schema -> Identity Schema
forall s a. HasEnum s a => Lens' s a
Lens' Schema (Maybe [Value])
enum_ ((Maybe [Value] -> Identity (Maybe [Value]))
 -> Schema -> Identity Schema)
-> [Value] -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [Text -> Value
forall a. ToJSON a => a -> Value
toJSON Text
val]

-- | A element together with its rendered html representation.
data Rendered a
    = Rendered
    { forall a. Rendered a -> a
element :: a
    -- ^ the element itself
    , forall a. Rendered a -> Text
html :: Text
    -- ^ the html representation of the element.
    -- TODO: @ByteString@ might be better suited!
    }
    deriving ((forall x. Rendered a -> Rep (Rendered a) x)
-> (forall x. Rep (Rendered a) x -> Rendered a)
-> Generic (Rendered a)
forall x. Rep (Rendered a) x -> Rendered a
forall x. Rendered a -> Rep (Rendered a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Rendered a) x -> Rendered a
forall a x. Rendered a -> Rep (Rendered a) x
$cfrom :: forall a x. Rendered a -> Rep (Rendered a) x
from :: forall x. Rendered a -> Rep (Rendered a) x
$cto :: forall a x. Rep (Rendered a) x -> Rendered a
to :: forall x. Rep (Rendered a) x -> Rendered a
Generic)

instance (ToJSON a) => ToJSON (Rendered a)

instance (FromJSON a) => FromJSON (Rendered a)

instance (ToSchema a) => ToSchema (Rendered a)