{-# LANGUAGE OverloadedStrings #-}
module Pangraph.FGL (convert, revert) where
import Data.ByteString (ByteString)
import Data.ByteString.Char8 (pack)
import qualified Data.Graph.Inductive.Graph as FGL
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Maybe (fromJust)
import Data.Monoid ((<>))
import Pangraph
import Pangraph.Internal.ProtoGraph
convert :: Pangraph -> ([FGL.LNode ByteString], [FGL.LEdge Int])
convert p = let
vertexSet :: Set VertexID
vertexSet = (Set.fromList . map vertexID . vertexList) p
fglVertices :: [(Int, VertexID)]
fglVertices = zip [0..] (Set.toAscList vertexSet)
findIndexOfVertex :: VertexID -> Int
findIndexOfVertex v = Set.findIndex v vertexSet
fglEdges :: [(FGL.Node, FGL.Node, Int)]
fglEdges = let
in map ((\(e, (a,b)) ->
(findIndexOfVertex a, findIndexOfVertex b, e)) .
(\e -> ((fromJust . edgeID) e, edgeEndpoints e))) (edgeList p)
in (fglVertices, fglEdges)
revert :: ([FGL.LNode ByteString], [FGL.LEdge Int]) -> Maybe Pangraph
revert t = let
vf :: ProtoVertex -> VertexID
vf v = (fromJust . lookup "id") (protoVertexAttributes v)
ef :: ProtoEdge -> (VertexID, VertexID)
ef e = let
lookup' :: Value -> VertexID
lookup' value = (fromJust . lookup value) (protoEdgeAttributes e)
in (lookup' "source", lookup' "target")
in buildPangraph (FGL t) vf ef
newtype FGL = FGL ([FGL.LNode ByteString], [FGL.LEdge Int])
instance BuildPangraph FGL where
getProtoVertex (FGL (ns, _)) = map (\n -> makeProtoVertex [("id", snd n)]) ns
getProtoEdge (FGL (_, es)) = let
ps :: Show a => a -> ByteString
ps = pack . show
in map (\(src, dst, _) -> makeProtoEdge [("source", "n" <> ps src), ("target", "n" <> ps dst)]) es