module Docs.Hasql.TreeEdge
    ( TreeEdge (..)
    , TreeEdgeChildRef (..)
    , TreeEdgeChild (..)
    ) where

import GHC.Int (Int64)

import Docs.Hash (Hash, Hashable (..))
import Docs.TextElement (TextElement, TextElementID)
import Docs.Tree (NodeHeader)

data TreeEdgeChild
    = TreeEdgeToTextElement TextElement
    | TreeEdgeToNode Hash NodeHeader

data TreeEdgeChildRef
    = TreeEdgeRefToTextElement TextElementID
    | TreeEdgeRefToNode Hash

instance Hashable TreeEdgeChildRef where
    updateHash :: Ctx -> TreeEdgeChildRef -> Ctx
updateHash Ctx
ctx (TreeEdgeRefToTextElement TextElementID
elementID) =
        Ctx -> TextElementID -> Ctx
forall a. Hashable a => Ctx -> a -> Ctx
updateHash Ctx
ctx TextElementID
elementID
    updateHash Ctx
ctx (TreeEdgeRefToNode Hash
nodeHash) = Ctx -> Hash -> Ctx
forall a. Hashable a => Ctx -> a -> Ctx
updateHash Ctx
ctx Hash
nodeHash

data TreeEdge = TreeEdge
    { TreeEdge -> Hash
parentHash :: Hash
    , TreeEdge -> Int64
position :: Int64
    , TreeEdge -> TreeEdgeChildRef
child :: TreeEdgeChildRef
    }

instance Hashable TreeEdge where
    updateHash :: Ctx -> TreeEdge -> Ctx
updateHash = (TreeEdge -> Ctx -> Ctx) -> Ctx -> TreeEdge -> Ctx
forall a b c. (a -> b -> c) -> b -> a -> c
flip TreeEdge -> Ctx -> Ctx
updateHash'
      where
        updateHash' :: TreeEdge -> Ctx -> Ctx
updateHash' TreeEdge
edge =
            (Ctx -> Int64 -> Ctx) -> Int64 -> Ctx -> Ctx
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ctx -> Int64 -> Ctx
forall a. Hashable a => Ctx -> a -> Ctx
updateHash (TreeEdge -> Int64
position TreeEdge
edge)
                (Ctx -> Ctx) -> (Ctx -> Ctx) -> Ctx -> Ctx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ctx -> TreeEdgeChildRef -> Ctx) -> TreeEdgeChildRef -> Ctx -> Ctx
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ctx -> TreeEdgeChildRef -> Ctx
forall a. Hashable a => Ctx -> a -> Ctx
updateHash (TreeEdge -> TreeEdgeChildRef
child TreeEdge
edge)