{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE NoFieldSelectors #-} module WikiMusic.Model.Thread ( Thread (..), ThreadRender (..), mkThreads, renderThread, ) where import Data.Aeson import Data.OpenApi import Optics import Relude data Thread a = Thread a [Thread a] deriving (Thread a -> Thread a -> Bool (Thread a -> Thread a -> Bool) -> (Thread a -> Thread a -> Bool) -> Eq (Thread a) forall a. Eq a => Thread a -> Thread a -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: forall a. Eq a => Thread a -> Thread a -> Bool == :: Thread a -> Thread a -> Bool $c/= :: forall a. Eq a => Thread a -> Thread a -> Bool /= :: Thread a -> Thread a -> Bool Eq, Int -> Thread a -> ShowS [Thread a] -> ShowS Thread a -> String (Int -> Thread a -> ShowS) -> (Thread a -> String) -> ([Thread a] -> ShowS) -> Show (Thread a) forall a. Show a => Int -> Thread a -> ShowS forall a. Show a => [Thread a] -> ShowS forall a. Show a => Thread a -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: forall a. Show a => Int -> Thread a -> ShowS showsPrec :: Int -> Thread a -> ShowS $cshow :: forall a. Show a => Thread a -> String show :: Thread a -> String $cshowList :: forall a. Show a => [Thread a] -> ShowS showList :: [Thread a] -> ShowS Show, (forall x. Thread a -> Rep (Thread a) x) -> (forall x. Rep (Thread a) x -> Thread a) -> Generic (Thread a) forall x. Rep (Thread a) x -> Thread a forall x. Thread a -> Rep (Thread a) x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a forall a x. Rep (Thread a) x -> Thread a forall a x. Thread a -> Rep (Thread a) x $cfrom :: forall a x. Thread a -> Rep (Thread a) x from :: forall x. Thread a -> Rep (Thread a) x $cto :: forall a x. Rep (Thread a) x -> Thread a to :: forall x. Rep (Thread a) x -> Thread a Generic, Maybe (Thread a) Value -> Parser [Thread a] Value -> Parser (Thread a) (Value -> Parser (Thread a)) -> (Value -> Parser [Thread a]) -> Maybe (Thread a) -> FromJSON (Thread a) forall a. FromJSON a => Maybe (Thread a) forall a. FromJSON a => Value -> Parser [Thread a] forall a. FromJSON a => Value -> Parser (Thread a) forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> Maybe a -> FromJSON a $cparseJSON :: forall a. FromJSON a => Value -> Parser (Thread a) parseJSON :: Value -> Parser (Thread a) $cparseJSONList :: forall a. FromJSON a => Value -> Parser [Thread a] parseJSONList :: Value -> Parser [Thread a] $comittedField :: forall a. FromJSON a => Maybe (Thread a) omittedField :: Maybe (Thread a) FromJSON, [Thread a] -> Value [Thread a] -> Encoding Thread a -> Bool Thread a -> Value Thread a -> Encoding (Thread a -> Value) -> (Thread a -> Encoding) -> ([Thread a] -> Value) -> ([Thread a] -> Encoding) -> (Thread a -> Bool) -> ToJSON (Thread a) forall a. ToJSON a => [Thread a] -> Value forall a. ToJSON a => [Thread a] -> Encoding forall a. ToJSON a => Thread a -> Bool forall a. ToJSON a => Thread a -> Value forall a. ToJSON a => Thread a -> Encoding forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> (a -> Bool) -> ToJSON a $ctoJSON :: forall a. ToJSON a => Thread a -> Value toJSON :: Thread a -> Value $ctoEncoding :: forall a. ToJSON a => Thread a -> Encoding toEncoding :: Thread a -> Encoding $ctoJSONList :: forall a. ToJSON a => [Thread a] -> Value toJSONList :: [Thread a] -> Value $ctoEncodingList :: forall a. ToJSON a => [Thread a] -> Encoding toEncodingList :: [Thread a] -> Encoding $comitField :: forall a. ToJSON a => Thread a -> Bool omitField :: Thread a -> Bool ToJSON) data ThreadRender a = ThreadRender { forall a. ThreadRender a -> a node :: a, forall a. ThreadRender a -> [ThreadRender a] subNodes :: [ThreadRender a] } deriving (ThreadRender a -> ThreadRender a -> Bool (ThreadRender a -> ThreadRender a -> Bool) -> (ThreadRender a -> ThreadRender a -> Bool) -> Eq (ThreadRender a) forall a. Eq a => ThreadRender a -> ThreadRender a -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: forall a. Eq a => ThreadRender a -> ThreadRender a -> Bool == :: ThreadRender a -> ThreadRender a -> Bool $c/= :: forall a. Eq a => ThreadRender a -> ThreadRender a -> Bool /= :: ThreadRender a -> ThreadRender a -> Bool Eq, Int -> ThreadRender a -> ShowS [ThreadRender a] -> ShowS ThreadRender a -> String (Int -> ThreadRender a -> ShowS) -> (ThreadRender a -> String) -> ([ThreadRender a] -> ShowS) -> Show (ThreadRender a) forall a. Show a => Int -> ThreadRender a -> ShowS forall a. Show a => [ThreadRender a] -> ShowS forall a. Show a => ThreadRender a -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: forall a. Show a => Int -> ThreadRender a -> ShowS showsPrec :: Int -> ThreadRender a -> ShowS $cshow :: forall a. Show a => ThreadRender a -> String show :: ThreadRender a -> String $cshowList :: forall a. Show a => [ThreadRender a] -> ShowS showList :: [ThreadRender a] -> ShowS Show, (forall x. ThreadRender a -> Rep (ThreadRender a) x) -> (forall x. Rep (ThreadRender a) x -> ThreadRender a) -> Generic (ThreadRender a) forall x. Rep (ThreadRender a) x -> ThreadRender a forall x. ThreadRender a -> Rep (ThreadRender a) x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a forall a x. Rep (ThreadRender a) x -> ThreadRender a forall a x. ThreadRender a -> Rep (ThreadRender a) x $cfrom :: forall a x. ThreadRender a -> Rep (ThreadRender a) x from :: forall x. ThreadRender a -> Rep (ThreadRender a) x $cto :: forall a x. Rep (ThreadRender a) x -> ThreadRender a to :: forall x. Rep (ThreadRender a) x -> ThreadRender a Generic, Maybe (ThreadRender a) Value -> Parser [ThreadRender a] Value -> Parser (ThreadRender a) (Value -> Parser (ThreadRender a)) -> (Value -> Parser [ThreadRender a]) -> Maybe (ThreadRender a) -> FromJSON (ThreadRender a) forall a. FromJSON a => Maybe (ThreadRender a) forall a. FromJSON a => Value -> Parser [ThreadRender a] forall a. FromJSON a => Value -> Parser (ThreadRender a) forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> Maybe a -> FromJSON a $cparseJSON :: forall a. FromJSON a => Value -> Parser (ThreadRender a) parseJSON :: Value -> Parser (ThreadRender a) $cparseJSONList :: forall a. FromJSON a => Value -> Parser [ThreadRender a] parseJSONList :: Value -> Parser [ThreadRender a] $comittedField :: forall a. FromJSON a => Maybe (ThreadRender a) omittedField :: Maybe (ThreadRender a) FromJSON, [ThreadRender a] -> Value [ThreadRender a] -> Encoding ThreadRender a -> Bool ThreadRender a -> Value ThreadRender a -> Encoding (ThreadRender a -> Value) -> (ThreadRender a -> Encoding) -> ([ThreadRender a] -> Value) -> ([ThreadRender a] -> Encoding) -> (ThreadRender a -> Bool) -> ToJSON (ThreadRender a) forall a. ToJSON a => [ThreadRender a] -> Value forall a. ToJSON a => [ThreadRender a] -> Encoding forall a. ToJSON a => ThreadRender a -> Bool forall a. ToJSON a => ThreadRender a -> Value forall a. ToJSON a => ThreadRender a -> Encoding forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> (a -> Bool) -> ToJSON a $ctoJSON :: forall a. ToJSON a => ThreadRender a -> Value toJSON :: ThreadRender a -> Value $ctoEncoding :: forall a. ToJSON a => ThreadRender a -> Encoding toEncoding :: ThreadRender a -> Encoding $ctoJSONList :: forall a. ToJSON a => [ThreadRender a] -> Value toJSONList :: [ThreadRender a] -> Value $ctoEncodingList :: forall a. ToJSON a => [ThreadRender a] -> Encoding toEncodingList :: [ThreadRender a] -> Encoding $comitField :: forall a. ToJSON a => ThreadRender a -> Bool omitField :: ThreadRender a -> Bool ToJSON) instance (ToSchema a) => ToSchema (ThreadRender a) makeFieldLabelsNoPrefix ''Thread renderThread :: Thread a -> ThreadRender a renderThread :: forall a. Thread a -> ThreadRender a renderThread (Thread a x [Thread a] xs) = do ThreadRender {$sel:node:ThreadRender :: a node = a x, $sel:subNodes:ThreadRender :: [ThreadRender a] subNodes = (Thread a -> ThreadRender a) -> [Thread a] -> [ThreadRender a] forall a b. (a -> b) -> [a] -> [b] map Thread a -> ThreadRender a forall a. Thread a -> ThreadRender a renderThread [Thread a] xs} mkThreads :: [a] -> (a -> a -> Bool) -> (a -> Maybe b) -> [Thread a] mkThreads :: forall a b. [a] -> (a -> a -> Bool) -> (a -> Maybe b) -> [Thread a] mkThreads [a] nodes a -> a -> Bool isChildOf a -> Maybe b getParentIdentifier = [Thread a] -> [Thread a] filterRootNodes ([Thread a] -> [Thread a]) -> [Thread a] -> [Thread a] forall a b. (a -> b) -> a -> b $ (a -> Thread a) -> [a] -> [Thread a] forall a b. (a -> b) -> [a] -> [b] map a -> Thread a withThreadChildren [a] nodes where directChildren :: a -> [a] directChildren a node = (a -> Bool) -> [a] -> [a] forall a. (a -> Bool) -> [a] -> [a] filter (a -> a -> Bool isChildOf a node) [a] nodes withThreadChildren :: a -> Thread a withThreadChildren a node = a -> [Thread a] -> Thread a forall a. a -> [Thread a] -> Thread a Thread a node ([Thread a] -> Thread a) -> [Thread a] -> Thread a forall a b. (a -> b) -> a -> b $ (a -> Thread a) -> [a] -> [Thread a] forall a b. (a -> b) -> [a] -> [b] map a -> Thread a withThreadChildren (a -> [a] directChildren a node) filterRootNodes :: [Thread a] -> [Thread a] filterRootNodes = (Thread a -> Bool) -> [Thread a] -> [Thread a] forall a. (a -> Bool) -> [a] -> [a] filter (\(Thread a x [Thread a] _) -> Maybe b -> Bool forall a. Maybe a -> Bool isNothing (a -> Maybe b getParentIdentifier a x))