{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
-- |
-- Module: NetSpider.Found
-- Description: Types about local findings
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- 
module NetSpider.Found
       ( -- * Local findings
         FoundNode(..),
         FoundLink(..),
         -- * LinkState
         LinkState(..),
         linkStateToText,
         linkStateFromText,
         -- * Utilities
         sortByTime,
         allTargetNodes
       ) where

import qualified Control.Monad.Fail as Fail
import Data.Aeson (FromJSON(..), ToJSON(..))
import qualified Data.Aeson as Aeson
import Data.Bifunctor (Bifunctor(..))
import Data.Char (isUpper, toLower)
import Data.Greskell (FromGraphSON(..))
import Data.List (sortOn, reverse)
import Data.Text (Text, unpack)
import GHC.Generics (Generic)
import qualified Text.Regex.Applicative as RE

import NetSpider.Timestamp (Timestamp)

-- | State of the found link.
data LinkState =
    LinkUnused
    -- ^ Link is possible, but not used.
  | LinkToTarget
    -- ^ Link is directional. It's from subject to target.
  | LinkToSubject
    -- ^ Link is directional. It's from target to subject.
  | LinkBidirectional
    -- ^ Link is bidirectional.
  deriving (Int -> LinkState -> ShowS
[LinkState] -> ShowS
LinkState -> String
(Int -> LinkState -> ShowS)
-> (LinkState -> String)
-> ([LinkState] -> ShowS)
-> Show LinkState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LinkState] -> ShowS
$cshowList :: [LinkState] -> ShowS
show :: LinkState -> String
$cshow :: LinkState -> String
showsPrec :: Int -> LinkState -> ShowS
$cshowsPrec :: Int -> LinkState -> ShowS
Show,LinkState -> LinkState -> Bool
(LinkState -> LinkState -> Bool)
-> (LinkState -> LinkState -> Bool) -> Eq LinkState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LinkState -> LinkState -> Bool
$c/= :: LinkState -> LinkState -> Bool
== :: LinkState -> LinkState -> Bool
$c== :: LinkState -> LinkState -> Bool
Eq,Eq LinkState
Eq LinkState
-> (LinkState -> LinkState -> Ordering)
-> (LinkState -> LinkState -> Bool)
-> (LinkState -> LinkState -> Bool)
-> (LinkState -> LinkState -> Bool)
-> (LinkState -> LinkState -> Bool)
-> (LinkState -> LinkState -> LinkState)
-> (LinkState -> LinkState -> LinkState)
-> Ord LinkState
LinkState -> LinkState -> Bool
LinkState -> LinkState -> Ordering
LinkState -> LinkState -> LinkState
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
min :: LinkState -> LinkState -> LinkState
$cmin :: LinkState -> LinkState -> LinkState
max :: LinkState -> LinkState -> LinkState
$cmax :: LinkState -> LinkState -> LinkState
>= :: LinkState -> LinkState -> Bool
$c>= :: LinkState -> LinkState -> Bool
> :: LinkState -> LinkState -> Bool
$c> :: LinkState -> LinkState -> Bool
<= :: LinkState -> LinkState -> Bool
$c<= :: LinkState -> LinkState -> Bool
< :: LinkState -> LinkState -> Bool
$c< :: LinkState -> LinkState -> Bool
compare :: LinkState -> LinkState -> Ordering
$ccompare :: LinkState -> LinkState -> Ordering
$cp1Ord :: Eq LinkState
Ord,LinkState
LinkState -> LinkState -> Bounded LinkState
forall a. a -> a -> Bounded a
maxBound :: LinkState
$cmaxBound :: LinkState
minBound :: LinkState
$cminBound :: LinkState
Bounded,Int -> LinkState
LinkState -> Int
LinkState -> [LinkState]
LinkState -> LinkState
LinkState -> LinkState -> [LinkState]
LinkState -> LinkState -> LinkState -> [LinkState]
(LinkState -> LinkState)
-> (LinkState -> LinkState)
-> (Int -> LinkState)
-> (LinkState -> Int)
-> (LinkState -> [LinkState])
-> (LinkState -> LinkState -> [LinkState])
-> (LinkState -> LinkState -> [LinkState])
-> (LinkState -> LinkState -> LinkState -> [LinkState])
-> Enum LinkState
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: LinkState -> LinkState -> LinkState -> [LinkState]
$cenumFromThenTo :: LinkState -> LinkState -> LinkState -> [LinkState]
enumFromTo :: LinkState -> LinkState -> [LinkState]
$cenumFromTo :: LinkState -> LinkState -> [LinkState]
enumFromThen :: LinkState -> LinkState -> [LinkState]
$cenumFromThen :: LinkState -> LinkState -> [LinkState]
enumFrom :: LinkState -> [LinkState]
$cenumFrom :: LinkState -> [LinkState]
fromEnum :: LinkState -> Int
$cfromEnum :: LinkState -> Int
toEnum :: Int -> LinkState
$ctoEnum :: Int -> LinkState
pred :: LinkState -> LinkState
$cpred :: LinkState -> LinkState
succ :: LinkState -> LinkState
$csucc :: LinkState -> LinkState
Enum)

linkStateToText :: LinkState -> Text
linkStateToText :: LinkState -> Text
linkStateToText LinkState
ls = case LinkState
ls of
  LinkState
LinkUnused -> Text
"unused"
  LinkState
LinkToTarget -> Text
"to_target"
  LinkState
LinkToSubject -> Text
"to_subject"
  LinkState
LinkBidirectional -> Text
"bidirectional"

linkStateFromText :: Text -> Maybe LinkState
linkStateFromText :: Text -> Maybe LinkState
linkStateFromText Text
t = case Text
t of
  Text
"unused" -> LinkState -> Maybe LinkState
forall a. a -> Maybe a
Just LinkState
LinkUnused
  Text
"to_target" -> LinkState -> Maybe LinkState
forall a. a -> Maybe a
Just LinkState
LinkToTarget
  Text
"to_subject" -> LinkState -> Maybe LinkState
forall a. a -> Maybe a
Just LinkState
LinkToSubject
  Text
"bidirectional" -> LinkState -> Maybe LinkState
forall a. a -> Maybe a
Just LinkState
LinkBidirectional
  Text
_ -> Maybe LinkState
forall a. Maybe a
Nothing

linkStateFromTextF :: Fail.MonadFail m => Text -> m LinkState
linkStateFromTextF :: Text -> m LinkState
linkStateFromTextF Text
t = 
  case Text -> Maybe LinkState
linkStateFromText Text
t of
    Just LinkState
ls -> LinkState -> m LinkState
forall (m :: * -> *) a. Monad m => a -> m a
return LinkState
ls
    Maybe LinkState
Nothing -> String -> m LinkState
forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail (String
"Unrecognized LinkState: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
unpack Text
t)

instance FromGraphSON LinkState where
  parseGraphSON :: GValue -> Parser LinkState
parseGraphSON GValue
gv = Text -> Parser LinkState
forall (m :: * -> *). MonadFail m => Text -> m LinkState
linkStateFromTextF (Text -> Parser LinkState) -> Parser Text -> Parser LinkState
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< GValue -> Parser Text
forall a. FromGraphSON a => GValue -> Parser a
parseGraphSON GValue
gv

-- | Parse a JSON string to 'LinkState'.
--
-- @since 0.4.1.0
instance FromJSON LinkState where
  parseJSON :: Value -> Parser LinkState
parseJSON Value
v = Text -> Parser LinkState
forall (m :: * -> *). MonadFail m => Text -> m LinkState
linkStateFromTextF (Text -> Parser LinkState) -> Parser Text -> Parser LinkState
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v

-- | Convert 'LinkState' to a JSON string.
--
-- @since 0.4.1.0
instance ToJSON LinkState where
  toJSON :: LinkState -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> (LinkState -> Text) -> LinkState -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LinkState -> Text
linkStateToText

aesonOpt :: Aeson.Options
aesonOpt :: Options
aesonOpt = Options
Aeson.defaultOptions
           { fieldLabelModifier :: ShowS
Aeson.fieldLabelModifier = ShowS
modifier
           }
  where
    modifier :: ShowS
modifier = RE Char String -> ShowS
forall s. RE s [s] -> [s] -> [s]
RE.replace RE Char String
reSnake ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RE Char String -> ShowS
forall s. RE s [s] -> [s] -> [s]
RE.replace RE Char String
reAttr
    reAttr :: RE Char String
reAttr = ShowS -> RE Char String -> RE Char String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> ShowS
forall a b. a -> b -> a
const String
"Attrs") (RE Char String -> RE Char String)
-> RE Char String -> RE Char String
forall a b. (a -> b) -> a -> b
$ String -> RE Char String
forall a. Eq a => [a] -> RE a [a]
RE.string String
"Attributes"
    reSnake :: RE Char String
reSnake = (Char -> Maybe String) -> RE Char String
forall s a. (s -> Maybe a) -> RE s a
RE.msym ((Char -> Maybe String) -> RE Char String)
-> (Char -> Maybe String) -> RE Char String
forall a b. (a -> b) -> a -> b
$ \Char
c -> if Char -> Bool
isUpper Char
c then String -> Maybe String
forall a. a -> Maybe a
Just [Char
'_', Char -> Char
toLower Char
c] else Maybe String
forall a. Maybe a
Nothing


-- | A link found at a 'FoundNode'. The link connects from the subject
-- node (the found node) to the target node. The link may be
-- directional or non-directional.
--
-- - type @n@: node ID.
-- - type @la@: link attributes.
data FoundLink n la =
  FoundLink
  { FoundLink n la -> n
targetNode :: n,
    FoundLink n la -> LinkState
linkState :: LinkState,
    FoundLink n la -> la
linkAttributes :: la
  }
  deriving (Int -> FoundLink n la -> ShowS
[FoundLink n la] -> ShowS
FoundLink n la -> String
(Int -> FoundLink n la -> ShowS)
-> (FoundLink n la -> String)
-> ([FoundLink n la] -> ShowS)
-> Show (FoundLink n la)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall n la. (Show n, Show la) => Int -> FoundLink n la -> ShowS
forall n la. (Show n, Show la) => [FoundLink n la] -> ShowS
forall n la. (Show n, Show la) => FoundLink n la -> String
showList :: [FoundLink n la] -> ShowS
$cshowList :: forall n la. (Show n, Show la) => [FoundLink n la] -> ShowS
show :: FoundLink n la -> String
$cshow :: forall n la. (Show n, Show la) => FoundLink n la -> String
showsPrec :: Int -> FoundLink n la -> ShowS
$cshowsPrec :: forall n la. (Show n, Show la) => Int -> FoundLink n la -> ShowS
Show,FoundLink n la -> FoundLink n la -> Bool
(FoundLink n la -> FoundLink n la -> Bool)
-> (FoundLink n la -> FoundLink n la -> Bool)
-> Eq (FoundLink n la)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall n la.
(Eq n, Eq la) =>
FoundLink n la -> FoundLink n la -> Bool
/= :: FoundLink n la -> FoundLink n la -> Bool
$c/= :: forall n la.
(Eq n, Eq la) =>
FoundLink n la -> FoundLink n la -> Bool
== :: FoundLink n la -> FoundLink n la -> Bool
$c== :: forall n la.
(Eq n, Eq la) =>
FoundLink n la -> FoundLink n la -> Bool
Eq,Eq (FoundLink n la)
Eq (FoundLink n la)
-> (FoundLink n la -> FoundLink n la -> Ordering)
-> (FoundLink n la -> FoundLink n la -> Bool)
-> (FoundLink n la -> FoundLink n la -> Bool)
-> (FoundLink n la -> FoundLink n la -> Bool)
-> (FoundLink n la -> FoundLink n la -> Bool)
-> (FoundLink n la -> FoundLink n la -> FoundLink n la)
-> (FoundLink n la -> FoundLink n la -> FoundLink n la)
-> Ord (FoundLink n la)
FoundLink n la -> FoundLink n la -> Bool
FoundLink n la -> FoundLink n la -> Ordering
FoundLink n la -> FoundLink n la -> FoundLink n la
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
forall n la. (Ord n, Ord la) => Eq (FoundLink n la)
forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Bool
forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Ordering
forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> FoundLink n la
min :: FoundLink n la -> FoundLink n la -> FoundLink n la
$cmin :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> FoundLink n la
max :: FoundLink n la -> FoundLink n la -> FoundLink n la
$cmax :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> FoundLink n la
>= :: FoundLink n la -> FoundLink n la -> Bool
$c>= :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Bool
> :: FoundLink n la -> FoundLink n la -> Bool
$c> :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Bool
<= :: FoundLink n la -> FoundLink n la -> Bool
$c<= :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Bool
< :: FoundLink n la -> FoundLink n la -> Bool
$c< :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Bool
compare :: FoundLink n la -> FoundLink n la -> Ordering
$ccompare :: forall n la.
(Ord n, Ord la) =>
FoundLink n la -> FoundLink n la -> Ordering
$cp1Ord :: forall n la. (Ord n, Ord la) => Eq (FoundLink n la)
Ord,(forall x. FoundLink n la -> Rep (FoundLink n la) x)
-> (forall x. Rep (FoundLink n la) x -> FoundLink n la)
-> Generic (FoundLink n la)
forall x. Rep (FoundLink n la) x -> FoundLink n la
forall x. FoundLink n la -> Rep (FoundLink n la) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall n la x. Rep (FoundLink n la) x -> FoundLink n la
forall n la x. FoundLink n la -> Rep (FoundLink n la) x
$cto :: forall n la x. Rep (FoundLink n la) x -> FoundLink n la
$cfrom :: forall n la x. FoundLink n la -> Rep (FoundLink n la) x
Generic)

-- | @since 0.3.0.0
instance Functor (FoundLink n) where
  fmap :: (a -> b) -> FoundLink n a -> FoundLink n b
fmap a -> b
f FoundLink n a
l = FoundLink n a
l { linkAttributes :: b
linkAttributes = a -> b
f (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ FoundLink n a -> a
forall n la. FoundLink n la -> la
linkAttributes FoundLink n a
l }

-- | @since 0.3.0.0
instance Bifunctor FoundLink where
  bimap :: (a -> b) -> (c -> d) -> FoundLink a c -> FoundLink b d
bimap a -> b
fn c -> d
fla FoundLink a c
l = FoundLink a c
l { targetNode :: b
targetNode = a -> b
fn (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ FoundLink a c -> a
forall n la. FoundLink n la -> n
targetNode FoundLink a c
l,
                       linkAttributes :: d
linkAttributes = c -> d
fla (c -> d) -> c -> d
forall a b. (a -> b) -> a -> b
$ FoundLink a c -> c
forall n la. FoundLink n la -> la
linkAttributes FoundLink a c
l
                     }

-- | @since 0.4.1.0
instance (FromJSON n, FromJSON la) => FromJSON (FoundLink n la) where
  parseJSON :: Value -> Parser (FoundLink n la)
parseJSON = Options -> Value -> Parser (FoundLink n la)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
Aeson.genericParseJSON Options
aesonOpt

-- | @since 0.4.1.0
instance (ToJSON n, ToJSON la) => ToJSON (FoundLink n la) where
  toJSON :: FoundLink n la -> Value
toJSON = Options -> FoundLink n la -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
Aeson.genericToJSON Options
aesonOpt
  toEncoding :: FoundLink n la -> Encoding
toEncoding = Options -> FoundLink n la -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding Options
aesonOpt

-- | 'FoundNode' is a node (the subject node) observed at a specific
-- time. It has a set of neighbor links found at the moment.
--
-- - type @n@: node ID.
-- - type @na@: node attributes.
-- - type @la@: link attributes.
--
-- 'Ord' instance is added in net-spider-0.4.1.0.
data FoundNode n na la =
  FoundNode
  { FoundNode n na la -> n
subjectNode :: n,
    FoundNode n na la -> Timestamp
foundAt :: Timestamp,
    FoundNode n na la -> [FoundLink n la]
neighborLinks :: [FoundLink n la],
    FoundNode n na la -> na
nodeAttributes :: na
  }
  deriving (Int -> FoundNode n na la -> ShowS
[FoundNode n na la] -> ShowS
FoundNode n na la -> String
(Int -> FoundNode n na la -> ShowS)
-> (FoundNode n na la -> String)
-> ([FoundNode n na la] -> ShowS)
-> Show (FoundNode n na la)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall n na la.
(Show n, Show la, Show na) =>
Int -> FoundNode n na la -> ShowS
forall n na la.
(Show n, Show la, Show na) =>
[FoundNode n na la] -> ShowS
forall n na la.
(Show n, Show la, Show na) =>
FoundNode n na la -> String
showList :: [FoundNode n na la] -> ShowS
$cshowList :: forall n na la.
(Show n, Show la, Show na) =>
[FoundNode n na la] -> ShowS
show :: FoundNode n na la -> String
$cshow :: forall n na la.
(Show n, Show la, Show na) =>
FoundNode n na la -> String
showsPrec :: Int -> FoundNode n na la -> ShowS
$cshowsPrec :: forall n na la.
(Show n, Show la, Show na) =>
Int -> FoundNode n na la -> ShowS
Show,FoundNode n na la -> FoundNode n na la -> Bool
(FoundNode n na la -> FoundNode n na la -> Bool)
-> (FoundNode n na la -> FoundNode n na la -> Bool)
-> Eq (FoundNode n na la)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall n na la.
(Eq n, Eq la, Eq na) =>
FoundNode n na la -> FoundNode n na la -> Bool
/= :: FoundNode n na la -> FoundNode n na la -> Bool
$c/= :: forall n na la.
(Eq n, Eq la, Eq na) =>
FoundNode n na la -> FoundNode n na la -> Bool
== :: FoundNode n na la -> FoundNode n na la -> Bool
$c== :: forall n na la.
(Eq n, Eq la, Eq na) =>
FoundNode n na la -> FoundNode n na la -> Bool
Eq,Eq (FoundNode n na la)
Eq (FoundNode n na la)
-> (FoundNode n na la -> FoundNode n na la -> Ordering)
-> (FoundNode n na la -> FoundNode n na la -> Bool)
-> (FoundNode n na la -> FoundNode n na la -> Bool)
-> (FoundNode n na la -> FoundNode n na la -> Bool)
-> (FoundNode n na la -> FoundNode n na la -> Bool)
-> (FoundNode n na la -> FoundNode n na la -> FoundNode n na la)
-> (FoundNode n na la -> FoundNode n na la -> FoundNode n na la)
-> Ord (FoundNode n na la)
FoundNode n na la -> FoundNode n na la -> Bool
FoundNode n na la -> FoundNode n na la -> Ordering
FoundNode n na la -> FoundNode n na la -> FoundNode n na la
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
forall n na la. (Ord n, Ord la, Ord na) => Eq (FoundNode n na la)
forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Bool
forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Ordering
forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> FoundNode n na la
min :: FoundNode n na la -> FoundNode n na la -> FoundNode n na la
$cmin :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> FoundNode n na la
max :: FoundNode n na la -> FoundNode n na la -> FoundNode n na la
$cmax :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> FoundNode n na la
>= :: FoundNode n na la -> FoundNode n na la -> Bool
$c>= :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Bool
> :: FoundNode n na la -> FoundNode n na la -> Bool
$c> :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Bool
<= :: FoundNode n na la -> FoundNode n na la -> Bool
$c<= :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Bool
< :: FoundNode n na la -> FoundNode n na la -> Bool
$c< :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Bool
compare :: FoundNode n na la -> FoundNode n na la -> Ordering
$ccompare :: forall n na la.
(Ord n, Ord la, Ord na) =>
FoundNode n na la -> FoundNode n na la -> Ordering
$cp1Ord :: forall n na la. (Ord n, Ord la, Ord na) => Eq (FoundNode n na la)
Ord,(forall x. FoundNode n na la -> Rep (FoundNode n na la) x)
-> (forall x. Rep (FoundNode n na la) x -> FoundNode n na la)
-> Generic (FoundNode n na la)
forall x. Rep (FoundNode n na la) x -> FoundNode n na la
forall x. FoundNode n na la -> Rep (FoundNode n na la) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall n na la x. Rep (FoundNode n na la) x -> FoundNode n na la
forall n na la x. FoundNode n na la -> Rep (FoundNode n na la) x
$cto :: forall n na la x. Rep (FoundNode n na la) x -> FoundNode n na la
$cfrom :: forall n na la x. FoundNode n na la -> Rep (FoundNode n na la) x
Generic)

-- | @since 0.3.0.0
instance Functor (FoundNode n na) where
  fmap :: (a -> b) -> FoundNode n na a -> FoundNode n na b
fmap a -> b
f FoundNode n na a
n = FoundNode n na a
n { neighborLinks :: [FoundLink n b]
neighborLinks = ((FoundLink n a -> FoundLink n b)
-> [FoundLink n a] -> [FoundLink n b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FoundLink n a -> FoundLink n b)
 -> [FoundLink n a] -> [FoundLink n b])
-> ((a -> b) -> FoundLink n a -> FoundLink n b)
-> (a -> b)
-> [FoundLink n a]
-> [FoundLink n b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> FoundLink n a -> FoundLink n b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) a -> b
f ([FoundLink n a] -> [FoundLink n b])
-> [FoundLink n a] -> [FoundLink n b]
forall a b. (a -> b) -> a -> b
$ FoundNode n na a -> [FoundLink n a]
forall n na la. FoundNode n na la -> [FoundLink n la]
neighborLinks FoundNode n na a
n }

-- | @since 0.3.0.0
instance Bifunctor (FoundNode n) where
  bimap :: (a -> b) -> (c -> d) -> FoundNode n a c -> FoundNode n b d
bimap a -> b
fna c -> d
fla FoundNode n a c
n = FoundNode n a c
n { neighborLinks :: [FoundLink n d]
neighborLinks = ((FoundLink n c -> FoundLink n d)
-> [FoundLink n c] -> [FoundLink n d]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FoundLink n c -> FoundLink n d)
 -> [FoundLink n c] -> [FoundLink n d])
-> ((c -> d) -> FoundLink n c -> FoundLink n d)
-> (c -> d)
-> [FoundLink n c]
-> [FoundLink n d]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> d) -> FoundLink n c -> FoundLink n d
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) c -> d
fla ([FoundLink n c] -> [FoundLink n d])
-> [FoundLink n c] -> [FoundLink n d]
forall a b. (a -> b) -> a -> b
$ FoundNode n a c -> [FoundLink n c]
forall n na la. FoundNode n na la -> [FoundLink n la]
neighborLinks FoundNode n a c
n,
                        nodeAttributes :: b
nodeAttributes = a -> b
fna (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ FoundNode n a c -> a
forall n na la. FoundNode n na la -> na
nodeAttributes FoundNode n a c
n
                      }

-- | @since 0.4.1.0
instance (FromJSON n, FromJSON na, FromJSON la) => FromJSON (FoundNode n na la) where
  parseJSON :: Value -> Parser (FoundNode n na la)
parseJSON = Options -> Value -> Parser (FoundNode n na la)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
Aeson.genericParseJSON Options
aesonOpt

-- | @since 0.4.1.0
instance (ToJSON n, ToJSON na, ToJSON la) => ToJSON (FoundNode n na la) where
  toJSON :: FoundNode n na la -> Value
toJSON = Options -> FoundNode n na la -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
Aeson.genericToJSON Options
aesonOpt
  toEncoding :: FoundNode n na la -> Encoding
toEncoding = Options -> FoundNode n na la -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding Options
aesonOpt

-- | Sort the list of 'FoundNode's by descending order of their
-- timestamps. The latest 'FoundNode' is at the top.
--
-- @since 0.4.2.0
sortByTime :: [FoundNode n na la] -> [FoundNode n na la]
sortByTime :: [FoundNode n na la] -> [FoundNode n na la]
sortByTime [FoundNode n na la]
fns = [FoundNode n na la] -> [FoundNode n na la]
forall a. [a] -> [a]
reverse ([FoundNode n na la] -> [FoundNode n na la])
-> [FoundNode n na la] -> [FoundNode n na la]
forall a b. (a -> b) -> a -> b
$ (FoundNode n na la -> Timestamp)
-> [FoundNode n na la] -> [FoundNode n na la]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn FoundNode n na la -> Timestamp
forall n na la. FoundNode n na la -> Timestamp
foundAt [FoundNode n na la]
fns

-- | Get all 'targetNode's of the 'FoundNode'.
--
-- @since 0.4.2.0
allTargetNodes :: FoundNode n na la -> [n]
allTargetNodes :: FoundNode n na la -> [n]
allTargetNodes = (FoundLink n la -> n) -> [FoundLink n la] -> [n]
forall a b. (a -> b) -> [a] -> [b]
map FoundLink n la -> n
forall n la. FoundLink n la -> n
targetNode ([FoundLink n la] -> [n])
-> (FoundNode n na la -> [FoundLink n la])
-> FoundNode n na la
-> [n]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FoundNode n na la -> [FoundLink n la]
forall n na la. FoundNode n na la -> [FoundLink n la]
neighborLinks