{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE StandaloneDeriving #-}

module Hercules.API.Result
  ( Result (..),
    toEither,
    fromEither,
    either,
  )
where

import Data.Aeson
  ( FromJSON (..),
    ToJSON (..),
    genericParseJSON,
    genericToEncoding,
    genericToJSON,
  )
import Data.Profunctor
  ( Profunctor,
    dimap,
  )
import Hercules.API.Prelude hiding (either)
import Prelude ()

data Result e a
  = Ok a
  | Error e
  deriving (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall e a x. Rep (Result e a) x -> Result e a
forall e a x. Result e a -> Rep (Result e a) x
$cto :: forall e a x. Rep (Result e a) x -> Result e a
$cfrom :: forall e a x. Result e a -> Rep (Result e a) x
Generic, Int -> Result e a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall e a. (Show a, Show e) => Int -> Result e a -> ShowS
forall e a. (Show a, Show e) => [Result e a] -> ShowS
forall e a. (Show a, Show e) => Result e a -> String
showList :: [Result e a] -> ShowS
$cshowList :: forall e a. (Show a, Show e) => [Result e a] -> ShowS
show :: Result e a -> String
$cshow :: forall e a. (Show a, Show e) => Result e a -> String
showsPrec :: Int -> Result e a -> ShowS
$cshowsPrec :: forall e a. (Show a, Show e) => Int -> Result e a -> ShowS
Show, ReadPrec [Result e a]
ReadPrec (Result e a)
ReadS [Result e a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall e a. (Read a, Read e) => ReadPrec [Result e a]
forall e a. (Read a, Read e) => ReadPrec (Result e a)
forall e a. (Read a, Read e) => Int -> ReadS (Result e a)
forall e a. (Read a, Read e) => ReadS [Result e a]
readListPrec :: ReadPrec [Result e a]
$creadListPrec :: forall e a. (Read a, Read e) => ReadPrec [Result e a]
readPrec :: ReadPrec (Result e a)
$creadPrec :: forall e a. (Read a, Read e) => ReadPrec (Result e a)
readList :: ReadS [Result e a]
$creadList :: forall e a. (Read a, Read e) => ReadS [Result e a]
readsPrec :: Int -> ReadS (Result e a)
$creadsPrec :: forall e a. (Read a, Read e) => Int -> ReadS (Result e a)
Read, Result e a -> Result e a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall e a. (Eq a, Eq e) => Result e a -> Result e a -> Bool
/= :: Result e a -> Result e a -> Bool
$c/= :: forall e a. (Eq a, Eq e) => Result e a -> Result e a -> Bool
== :: Result e a -> Result e a -> Bool
$c== :: forall e a. (Eq a, Eq e) => Result e a -> Result e a -> Bool
Eq, Result e a -> Result e a -> Bool
Result e a -> Result e a -> Ordering
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 {e} {a}. (Ord a, Ord e) => Eq (Result e a)
forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Bool
forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Ordering
forall e a.
(Ord a, Ord e) =>
Result e a -> Result e a -> Result e a
min :: Result e a -> Result e a -> Result e a
$cmin :: forall e a.
(Ord a, Ord e) =>
Result e a -> Result e a -> Result e a
max :: Result e a -> Result e a -> Result e a
$cmax :: forall e a.
(Ord a, Ord e) =>
Result e a -> Result e a -> Result e a
>= :: Result e a -> Result e a -> Bool
$c>= :: forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Bool
> :: Result e a -> Result e a -> Bool
$c> :: forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Bool
<= :: Result e a -> Result e a -> Bool
$c<= :: forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Bool
< :: Result e a -> Result e a -> Bool
$c< :: forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Bool
compare :: Result e a -> Result e a -> Ordering
$ccompare :: forall e a. (Ord a, Ord e) => Result e a -> Result e a -> Ordering
Ord, forall a. (a -> ()) -> NFData a
forall e a. (NFData a, NFData e) => Result e a -> ()
rnf :: Result e a -> ()
$crnf :: forall e a. (NFData a, NFData e) => Result e a -> ()
NFData, forall a b. a -> Result e b -> Result e a
forall a b. (a -> b) -> Result e a -> Result e b
forall e a b. a -> Result e b -> Result e a
forall e a b. (a -> b) -> Result e a -> Result e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Result e b -> Result e a
$c<$ :: forall e a b. a -> Result e b -> Result e a
fmap :: forall a b. (a -> b) -> Result e a -> Result e b
$cfmap :: forall e a b. (a -> b) -> Result e a -> Result e b
Functor, forall a. Result e a -> Bool
forall e a. Eq a => a -> Result e a -> Bool
forall e a. Num a => Result e a -> a
forall e a. Ord a => Result e a -> a
forall m a. Monoid m => (a -> m) -> Result e a -> m
forall e m. Monoid m => Result e m -> m
forall e a. Result e a -> Bool
forall e a. Result e a -> Int
forall e a. Result e a -> [a]
forall a b. (a -> b -> b) -> b -> Result e a -> b
forall e a. (a -> a -> a) -> Result e a -> a
forall e m a. Monoid m => (a -> m) -> Result e a -> m
forall e b a. (b -> a -> b) -> b -> Result e a -> b
forall e a b. (a -> b -> b) -> b -> Result e a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => Result e a -> a
$cproduct :: forall e a. Num a => Result e a -> a
sum :: forall a. Num a => Result e a -> a
$csum :: forall e a. Num a => Result e a -> a
minimum :: forall a. Ord a => Result e a -> a
$cminimum :: forall e a. Ord a => Result e a -> a
maximum :: forall a. Ord a => Result e a -> a
$cmaximum :: forall e a. Ord a => Result e a -> a
elem :: forall a. Eq a => a -> Result e a -> Bool
$celem :: forall e a. Eq a => a -> Result e a -> Bool
length :: forall a. Result e a -> Int
$clength :: forall e a. Result e a -> Int
null :: forall a. Result e a -> Bool
$cnull :: forall e a. Result e a -> Bool
toList :: forall a. Result e a -> [a]
$ctoList :: forall e a. Result e a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Result e a -> a
$cfoldl1 :: forall e a. (a -> a -> a) -> Result e a -> a
foldr1 :: forall a. (a -> a -> a) -> Result e a -> a
$cfoldr1 :: forall e a. (a -> a -> a) -> Result e a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> Result e a -> b
$cfoldl' :: forall e b a. (b -> a -> b) -> b -> Result e a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Result e a -> b
$cfoldl :: forall e b a. (b -> a -> b) -> b -> Result e a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Result e a -> b
$cfoldr' :: forall e a b. (a -> b -> b) -> b -> Result e a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Result e a -> b
$cfoldr :: forall e a b. (a -> b -> b) -> b -> Result e a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> Result e a -> m
$cfoldMap' :: forall e m a. Monoid m => (a -> m) -> Result e a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Result e a -> m
$cfoldMap :: forall e m a. Monoid m => (a -> m) -> Result e a -> m
fold :: forall m. Monoid m => Result e m -> m
$cfold :: forall e m. Monoid m => Result e m -> m
Foldable, forall e. Functor (Result e)
forall e. Foldable (Result e)
forall e (m :: * -> *) a.
Monad m =>
Result e (m a) -> m (Result e a)
forall e (f :: * -> *) a.
Applicative f =>
Result e (f a) -> f (Result e a)
forall e (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Result e a -> m (Result e b)
forall e (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Result e a -> f (Result e b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Result e a -> f (Result e b)
sequence :: forall (m :: * -> *) a. Monad m => Result e (m a) -> m (Result e a)
$csequence :: forall e (m :: * -> *) a.
Monad m =>
Result e (m a) -> m (Result e a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Result e a -> m (Result e b)
$cmapM :: forall e (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Result e a -> m (Result e b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Result e (f a) -> f (Result e a)
$csequenceA :: forall e (f :: * -> *) a.
Applicative f =>
Result e (f a) -> f (Result e a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Result e a -> f (Result e b)
$ctraverse :: forall e (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Result e a -> f (Result e b)
Traversable)

deriving instance (ToSchema e, ToSchema a) => ToSchema (Result e a)

-- many more typeclasses can be implemented
instance (FromJSON e, FromJSON a) => FromJSON (Result e a) where
  parseJSON :: Value -> Parser (Result e a)
parseJSON = forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
schemaCompatibleOptions

instance (ToJSON e, ToJSON a) => ToJSON (Result e a) where
  toJSON :: Result e a -> Value
toJSON = forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
schemaCompatibleOptions

  toEncoding :: Result e a -> Encoding
toEncoding = forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
schemaCompatibleOptions

either :: Iso (Result e a) (Result e' a') (Either e a) (Either e' a')
either :: forall e a e' a'.
Iso (Result e a) (Result e' a') (Either e a) (Either e' a')
either = forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso forall e a. Result e a -> Either e a
toEither forall e a. Either e a -> Result e a
fromEither

toEither :: Result e a -> Either e a
toEither :: forall e a. Result e a -> Either e a
toEither (Ok a
a) = forall a b. b -> Either a b
Right a
a
toEither (Error e
e) = forall a b. a -> Either a b
Left e
e

fromEither :: Either e a -> Result e a
fromEither :: forall e a. Either e a -> Result e a
fromEither (Right a
a) = forall e a. a -> Result e a
Ok a
a
fromEither (Left e
e) = forall e a. e -> Result e a
Error e
e

-- | See @lens@ package.
type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t)

iso :: (s -> a) -> (b -> t) -> Iso s t a b
iso :: forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso s -> a
sa b -> t
bt = forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap s -> a
sa (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> t
bt)