-- | A social account, as read from the single socials YAML list
module MathiasSM.Yaml.Social (
    Social (..),
    parseSocial,
    parseSocialsYaml,
) where

import Data.Aeson (Object)
import Data.Maybe (fromMaybe)
import MathiasSM.Metadata qualified as K
import MathiasSM.Yaml (Check (runCheck), optional, parseYamlList, required)

-- | What a social account needs to be listed
data Social = Social
    { Social -> String
socialIcon :: String
    , Social -> String
socialHref :: String
    , Social -> String
socialUsername :: String
    , Social -> Bool
socialShowContact :: Bool
    , Social -> Bool
socialShowAbout :: Bool
    }
    deriving (Social -> Social -> Bool
(Social -> Social -> Bool)
-> (Social -> Social -> Bool) -> Eq Social
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Social -> Social -> Bool
== :: Social -> Social -> Bool
$c/= :: Social -> Social -> Bool
/= :: Social -> Social -> Bool
Eq, Int -> Social -> ShowS
[Social] -> ShowS
Social -> String
(Int -> Social -> ShowS)
-> (Social -> String) -> ([Social] -> ShowS) -> Show Social
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Social -> ShowS
showsPrec :: Int -> Social -> ShowS
$cshow :: Social -> String
show :: Social -> String
$cshowList :: [Social] -> ShowS
showList :: [Social] -> ShowS
Show)

-- | Parses a social account, reporting every problem (not just the first)
parseSocial :: Object -> Either [String] Social
parseSocial :: Object -> Either [String] Social
parseSocial Object
o =
    Check Social -> Either [String] Social
forall a. Check a -> Either [String] a
runCheck
        ( String -> String -> String -> Bool -> Bool -> Social
Social
            (String -> String -> String -> Bool -> Bool -> Social)
-> Check String
-> Check (String -> String -> Bool -> Bool -> Social)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Key -> Check String
forall a. FromJSON a => Object -> Key -> Check a
required Object
o Key
K.Icon
            Check (String -> String -> Bool -> Bool -> Social)
-> Check String -> Check (String -> Bool -> Bool -> Social)
forall a b. Check (a -> b) -> Check a -> Check b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object -> Key -> Check String
forall a. FromJSON a => Object -> Key -> Check a
required Object
o Key
K.Href
            Check (String -> Bool -> Bool -> Social)
-> Check String -> Check (Bool -> Bool -> Social)
forall a b. Check (a -> b) -> Check a -> Check b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object -> Key -> Check String
forall a. FromJSON a => Object -> Key -> Check a
required Object
o Key
K.Username
            Check (Bool -> Bool -> Social)
-> Check Bool -> Check (Bool -> Social)
forall a b. Check (a -> b) -> Check a -> Check b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> Check (Maybe Bool) -> Check Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Key -> Check (Maybe Bool)
forall a. FromJSON a => Object -> Key -> Check (Maybe a)
optional Object
o Key
K.ShowContact)
            Check (Bool -> Social) -> Check Bool -> Check Social
forall a b. Check (a -> b) -> Check a -> Check b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> Check (Maybe Bool) -> Check Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Key -> Check (Maybe Bool)
forall a. FromJSON a => Object -> Key -> Check (Maybe a)
optional Object
o Key
K.ShowAbout)
        )

-- | 'parseSocial' on the contents of the socials file (a list of accounts)
parseSocialsYaml :: String -> Either [String] [Social]
parseSocialsYaml :: String -> Either [String] [Social]
parseSocialsYaml = String
-> (Object -> Either [String] Social)
-> String
-> Either [String] [Social]
forall a.
String
-> (Object -> Either [String] a) -> String -> Either [String] [a]
parseYamlList String
"social" Object -> Either [String] Social
parseSocial