module ProAbstract.Structure.IsTaggedOrBare
    ( TaggedOrBare (..)
    , IsTaggedOrBare (..)
    , tagged, bare
    ) where

import ProAbstract.Structure.Block
import ProAbstract.Structure.BlockTag
import ProAbstract.Structure.Fragment
import ProAbstract.Structure.Inline
import ProAbstract.Structure.Paragraph

data TaggedOrBare a =
    IsTagged (TaggedType a)
  | IsBare (BareType a)

tagged' :: Prism' (TaggedOrBare a) (TaggedType a)
tagged' :: Prism' (TaggedOrBare a) (TaggedType a)
tagged' = (TaggedType a -> TaggedOrBare a)
-> (TaggedOrBare a -> Maybe (TaggedType a))
-> Prism' (TaggedOrBare a) (TaggedType a)
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' TaggedType a -> TaggedOrBare a
forall a. TaggedType a -> TaggedOrBare a
IsTagged \case{ IsTagged TaggedType a
x -> TaggedType a -> Maybe (TaggedType a)
forall a. a -> Maybe a
Just TaggedType a
x; TaggedOrBare a
_ -> Maybe (TaggedType a)
forall a. Maybe a
Nothing }

bare' :: Prism' (TaggedOrBare a) (BareType a)
bare' :: Prism' (TaggedOrBare a) (BareType a)
bare' = (BareType a -> TaggedOrBare a)
-> (TaggedOrBare a -> Maybe (BareType a))
-> Prism' (TaggedOrBare a) (BareType a)
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' BareType a -> TaggedOrBare a
forall a. BareType a -> TaggedOrBare a
IsBare \case{ IsBare BareType a
x -> BareType a -> Maybe (BareType a)
forall a. a -> Maybe a
Just BareType a
x; TaggedOrBare a
_ -> Maybe (BareType a)
forall a. Maybe a
Nothing }

class IsTaggedOrBare a where

    type TaggedType a
    type BareType a

    taggedOrBare :: Iso' a (TaggedOrBare a)

tagged :: IsTaggedOrBare a => Prism' a (TaggedType a)
tagged :: Prism' a (TaggedType a)
tagged = Iso' a (TaggedOrBare a)
forall a. IsTaggedOrBare a => Iso' a (TaggedOrBare a)
taggedOrBare Iso' a (TaggedOrBare a)
-> Optic
     A_Prism
     NoIx
     (TaggedOrBare a)
     (TaggedOrBare a)
     (TaggedType a)
     (TaggedType a)
-> Prism' a (TaggedType a)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Prism
  NoIx
  (TaggedOrBare a)
  (TaggedOrBare a)
  (TaggedType a)
  (TaggedType a)
forall a. Prism' (TaggedOrBare a) (TaggedType a)
tagged'

bare :: IsTaggedOrBare a => Prism' a (BareType a)
bare :: Prism' a (BareType a)
bare = Iso' a (TaggedOrBare a)
forall a. IsTaggedOrBare a => Iso' a (TaggedOrBare a)
taggedOrBare Iso' a (TaggedOrBare a)
-> Optic
     A_Prism
     NoIx
     (TaggedOrBare a)
     (TaggedOrBare a)
     (BareType a)
     (BareType a)
-> Prism' a (BareType a)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Prism
  NoIx
  (TaggedOrBare a)
  (TaggedOrBare a)
  (BareType a)
  (BareType a)
forall a. Prism' (TaggedOrBare a) (BareType a)
bare'

instance IsTaggedOrBare (TaggedOrBare a) where

    type TaggedType (TaggedOrBare a) = TaggedType a
    type BareType (TaggedOrBare a) = BareType a

    taggedOrBare :: Iso' (TaggedOrBare a) (TaggedOrBare (TaggedOrBare a))
taggedOrBare = (TaggedOrBare a -> TaggedOrBare (TaggedOrBare a))
-> (TaggedOrBare (TaggedOrBare a) -> TaggedOrBare a)
-> Iso' (TaggedOrBare a) (TaggedOrBare (TaggedOrBare a))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso TaggedOrBare a -> TaggedOrBare (TaggedOrBare a)
f TaggedOrBare (TaggedOrBare a) -> TaggedOrBare a
g
      where
        f :: TaggedOrBare a -> TaggedOrBare (TaggedOrBare a)
f = \case
            IsTagged TaggedType a
x -> TaggedType (TaggedOrBare a) -> TaggedOrBare (TaggedOrBare a)
forall a. TaggedType a -> TaggedOrBare a
IsTagged TaggedType a
TaggedType (TaggedOrBare a)
x
            IsBare BareType a
x -> BareType (TaggedOrBare a) -> TaggedOrBare (TaggedOrBare a)
forall a. BareType a -> TaggedOrBare a
IsBare BareType a
BareType (TaggedOrBare a)
x
        g :: TaggedOrBare (TaggedOrBare a) -> TaggedOrBare a
g = \case
            IsTagged TaggedType (TaggedOrBare a)
x -> TaggedType a -> TaggedOrBare a
forall a. TaggedType a -> TaggedOrBare a
IsTagged TaggedType a
TaggedType (TaggedOrBare a)
x
            IsBare BareType (TaggedOrBare a)
x -> BareType a -> TaggedOrBare a
forall a. BareType a -> TaggedOrBare a
IsBare BareType a
BareType (TaggedOrBare a)
x

instance IsTaggedOrBare (Inline ann) where

    type TaggedType (Inline ann) = TaggedLines ann
    type BareType (Inline ann) = Fragment ann

    taggedOrBare :: Iso' (Inline ann) (TaggedOrBare (Inline ann))
taggedOrBare = (Inline ann -> TaggedOrBare (Inline ann))
-> (TaggedOrBare (Inline ann) -> Inline ann)
-> Iso' (Inline ann) (TaggedOrBare (Inline ann))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso Inline ann -> TaggedOrBare (Inline ann)
f TaggedOrBare (Inline ann) -> Inline ann
g
      where
        f :: Inline ann -> TaggedOrBare (Inline ann)
f = \case
            InlineFork TaggedLines ann
x -> TaggedType (Inline ann) -> TaggedOrBare (Inline ann)
forall a. TaggedType a -> TaggedOrBare a
IsTagged TaggedLines ann
TaggedType (Inline ann)
x
            InlinePlain Fragment ann
x -> BareType (Inline ann) -> TaggedOrBare (Inline ann)
forall a. BareType a -> TaggedOrBare a
IsBare Fragment ann
BareType (Inline ann)
x
        g :: TaggedOrBare (Inline ann) -> Inline ann
g = \case
            IsTagged TaggedType (Inline ann)
x -> TaggedLines ann -> Inline ann
forall ann. TaggedLines ann -> Inline ann
InlineFork TaggedLines ann
TaggedType (Inline ann)
x
            IsBare BareType (Inline ann)
x -> Fragment ann -> Inline ann
forall ann. Fragment ann -> Inline ann
InlinePlain Fragment ann
BareType (Inline ann)
x

instance IsTaggedOrBare (Block ann) where

    type TaggedType (Block ann) = BlockTag ann
    type BareType (Block ann) = Paragraph ann

    taggedOrBare :: Iso' (Block ann) (TaggedOrBare (Block ann))
taggedOrBare = (Block ann -> TaggedOrBare (Block ann))
-> (TaggedOrBare (Block ann) -> Block ann)
-> Iso' (Block ann) (TaggedOrBare (Block ann))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso Block ann -> TaggedOrBare (Block ann)
f TaggedOrBare (Block ann) -> Block ann
g
      where
        f :: Block ann -> TaggedOrBare (Block ann)
f = \case
            BlockPlain TaggedPlainBlock ann
x -> TaggedType (Block ann) -> TaggedOrBare (Block ann)
forall a. TaggedType a -> TaggedOrBare a
IsTagged (TaggedPlainBlock ann -> BlockTag ann
forall ann. TaggedPlainBlock ann -> BlockTag ann
BlockTagPlain TaggedPlainBlock ann
x)
            BlockFork TaggedBlocks ann
x -> TaggedType (Block ann) -> TaggedOrBare (Block ann)
forall a. TaggedType a -> TaggedOrBare a
IsTagged (TaggedBlocks ann -> BlockTag ann
forall ann. TaggedBlocks ann -> BlockTag ann
BlockTagFork TaggedBlocks ann
x)
            BlockParagraph Paragraph ann
x -> BareType (Block ann) -> TaggedOrBare (Block ann)
forall a. BareType a -> TaggedOrBare a
IsBare Paragraph ann
BareType (Block ann)
x
        g :: TaggedOrBare (Block ann) -> Block ann
g = \case
            IsTagged (BlockTagPlain x) -> TaggedPlainBlock ann -> Block ann
forall ann. TaggedPlainBlock ann -> Block ann
BlockPlain TaggedPlainBlock ann
x
            IsTagged (BlockTagFork x) -> TaggedBlocks ann -> Block ann
forall ann. TaggedBlocks ann -> Block ann
BlockFork TaggedBlocks ann
x
            IsBare BareType (Block ann)
x -> Paragraph ann -> Block ann
forall ann. Paragraph ann -> Block ann
BlockParagraph Paragraph ann
BareType (Block ann)
x