{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- | Provides parser for @$HOME/.netrc@ files
--
-- The implemented grammar is approximately:
--
-- > NETRC := (WS|<comment>)* (ENTRY (WS+ <comment>*)+)* ENTRY?
-- >
-- > ENTRY := 'machine' WS+ <value> WS+ ((account|username|password) WS+ <value>)*
-- >        | 'default' WS+ (('account'|'username'|'password') WS+ <value>)*
-- >        | 'macdef' <value> LF (<line> LF)* LF
-- >
-- > WS := (LF|SPC|TAB)
-- >
-- > <line>  := !LF+
-- > <value> := !WS+
-- > <comment> := '#' !LF* LF
--
-- As an extension to the @.netrc@-format as described in .e.g.
-- <http://linux.die.net/man/5/netrc netrc(5)>, @#@-style comments are
-- tolerated.  Comments are currently only allowed before, between,
-- and after @machine@\/@default@\/@macdef@ entries. Be aware though
-- that such @#@-comment are not supported by all @.netrc@-aware
-- applications, including @ftp(1)@.
module Network.NetRc
    ( -- * Types
      NetRc(..)
    , NetRcHost(..)
    , NetRcMacDef(..)

      -- * Formatters
    , netRcToBuilder
    , netRcToByteString

      -- * Parsers
    , netRcParsec
    , parseNetRc

      -- * Utilities
    , readUserNetRc
    ) where

import           Control.Applicative
import           Control.DeepSeq
import           Control.Monad
import           Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as LB
import           Data.Data
import           Data.Either (rights, lefts)
import           Data.List (intersperse)
#if !MIN_VERSION_base(4,20,0)
import           Data.List (foldl')
#endif
import           GHC.Generics
import           System.Environment
import           System.IO.Error
import qualified Text.Parsec as P
import qualified Text.Parsec.ByteString as P

-- | @machine@ and @default@ entries describe remote accounts
--
-- __Invariant__: fields must not contain any @TAB@s, @SPACE@, or @LF@s.
data NetRcHost = NetRcHost
    { NetRcHost -> ByteString
nrhName      :: !ByteString   -- ^ Remote machine name (@""@ for @default@-entries)
    , NetRcHost -> ByteString
nrhLogin     :: !ByteString   -- ^ @login@ property (@""@ if missing)
    , NetRcHost -> ByteString
nrhPassword  :: !ByteString   -- ^ @password@ property (@""@ if missing)
    , NetRcHost -> ByteString
nrhAccount   :: !ByteString   -- ^ @account@ property (@""@ if missing)
    , NetRcHost -> [NetRcMacDef]
nrhMacros    :: [NetRcMacDef] -- ^ associated @macdef@ entries
    } deriving (NetRcHost -> NetRcHost -> Bool
(NetRcHost -> NetRcHost -> Bool)
-> (NetRcHost -> NetRcHost -> Bool) -> Eq NetRcHost
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NetRcHost -> NetRcHost -> Bool
== :: NetRcHost -> NetRcHost -> Bool
$c/= :: NetRcHost -> NetRcHost -> Bool
/= :: NetRcHost -> NetRcHost -> Bool
Eq, Eq NetRcHost
Eq NetRcHost =>
(NetRcHost -> NetRcHost -> Ordering)
-> (NetRcHost -> NetRcHost -> Bool)
-> (NetRcHost -> NetRcHost -> Bool)
-> (NetRcHost -> NetRcHost -> Bool)
-> (NetRcHost -> NetRcHost -> Bool)
-> (NetRcHost -> NetRcHost -> NetRcHost)
-> (NetRcHost -> NetRcHost -> NetRcHost)
-> Ord NetRcHost
NetRcHost -> NetRcHost -> Bool
NetRcHost -> NetRcHost -> Ordering
NetRcHost -> NetRcHost -> NetRcHost
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
$ccompare :: NetRcHost -> NetRcHost -> Ordering
compare :: NetRcHost -> NetRcHost -> Ordering
$c< :: NetRcHost -> NetRcHost -> Bool
< :: NetRcHost -> NetRcHost -> Bool
$c<= :: NetRcHost -> NetRcHost -> Bool
<= :: NetRcHost -> NetRcHost -> Bool
$c> :: NetRcHost -> NetRcHost -> Bool
> :: NetRcHost -> NetRcHost -> Bool
$c>= :: NetRcHost -> NetRcHost -> Bool
>= :: NetRcHost -> NetRcHost -> Bool
$cmax :: NetRcHost -> NetRcHost -> NetRcHost
max :: NetRcHost -> NetRcHost -> NetRcHost
$cmin :: NetRcHost -> NetRcHost -> NetRcHost
min :: NetRcHost -> NetRcHost -> NetRcHost
Ord, Int -> NetRcHost -> ShowS
[NetRcHost] -> ShowS
NetRcHost -> String
(Int -> NetRcHost -> ShowS)
-> (NetRcHost -> String)
-> ([NetRcHost] -> ShowS)
-> Show NetRcHost
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NetRcHost -> ShowS
showsPrec :: Int -> NetRcHost -> ShowS
$cshow :: NetRcHost -> String
show :: NetRcHost -> String
$cshowList :: [NetRcHost] -> ShowS
showList :: [NetRcHost] -> ShowS
Show, Typeable NetRcHost
Typeable NetRcHost =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> NetRcHost -> c NetRcHost)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NetRcHost)
-> (NetRcHost -> Constr)
-> (NetRcHost -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NetRcHost))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRcHost))
-> ((forall b. Data b => b -> b) -> NetRcHost -> NetRcHost)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> NetRcHost -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> NetRcHost -> r)
-> (forall u. (forall d. Data d => d -> u) -> NetRcHost -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> NetRcHost -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost)
-> Data NetRcHost
NetRcHost -> Constr
NetRcHost -> DataType
(forall b. Data b => b -> b) -> NetRcHost -> NetRcHost
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> NetRcHost -> u
forall u. (forall d. Data d => d -> u) -> NetRcHost -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcHost -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcHost -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRcHost
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRcHost -> c NetRcHost
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRcHost)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRcHost)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRcHost -> c NetRcHost
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRcHost -> c NetRcHost
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRcHost
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRcHost
$ctoConstr :: NetRcHost -> Constr
toConstr :: NetRcHost -> Constr
$cdataTypeOf :: NetRcHost -> DataType
dataTypeOf :: NetRcHost -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRcHost)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRcHost)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRcHost)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRcHost)
$cgmapT :: (forall b. Data b => b -> b) -> NetRcHost -> NetRcHost
gmapT :: (forall b. Data b => b -> b) -> NetRcHost -> NetRcHost
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcHost -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcHost -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcHost -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcHost -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NetRcHost -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> NetRcHost -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NetRcHost -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NetRcHost -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcHost -> m NetRcHost
Data, (forall x. NetRcHost -> Rep NetRcHost x)
-> (forall x. Rep NetRcHost x -> NetRcHost) -> Generic NetRcHost
forall x. Rep NetRcHost x -> NetRcHost
forall x. NetRcHost -> Rep NetRcHost x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NetRcHost -> Rep NetRcHost x
from :: forall x. NetRcHost -> Rep NetRcHost x
$cto :: forall x. Rep NetRcHost x -> NetRcHost
to :: forall x. Rep NetRcHost x -> NetRcHost
Generic)

instance NFData NetRcHost where rnf :: NetRcHost -> ()
rnf !NetRcHost
_ = ()

-- | @macdef@ entries defining @ftp@ macros
data NetRcMacDef = NetRcMacDef
    { NetRcMacDef -> ByteString
nrmName :: !ByteString -- ^ Name of @macdef@ entry
                             --
                             -- __Invariant__: must not contain any @TAB@s, @SPACE@, or @LF@s
    , NetRcMacDef -> ByteString
nrmBody :: !ByteString -- ^ Raw @macdef@ body
                             --
                             -- __Invariant__: must not contain null-lines, i.e. consecutive @LF@s
    } deriving (NetRcMacDef -> NetRcMacDef -> Bool
(NetRcMacDef -> NetRcMacDef -> Bool)
-> (NetRcMacDef -> NetRcMacDef -> Bool) -> Eq NetRcMacDef
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NetRcMacDef -> NetRcMacDef -> Bool
== :: NetRcMacDef -> NetRcMacDef -> Bool
$c/= :: NetRcMacDef -> NetRcMacDef -> Bool
/= :: NetRcMacDef -> NetRcMacDef -> Bool
Eq, Eq NetRcMacDef
Eq NetRcMacDef =>
(NetRcMacDef -> NetRcMacDef -> Ordering)
-> (NetRcMacDef -> NetRcMacDef -> Bool)
-> (NetRcMacDef -> NetRcMacDef -> Bool)
-> (NetRcMacDef -> NetRcMacDef -> Bool)
-> (NetRcMacDef -> NetRcMacDef -> Bool)
-> (NetRcMacDef -> NetRcMacDef -> NetRcMacDef)
-> (NetRcMacDef -> NetRcMacDef -> NetRcMacDef)
-> Ord NetRcMacDef
NetRcMacDef -> NetRcMacDef -> Bool
NetRcMacDef -> NetRcMacDef -> Ordering
NetRcMacDef -> NetRcMacDef -> NetRcMacDef
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
$ccompare :: NetRcMacDef -> NetRcMacDef -> Ordering
compare :: NetRcMacDef -> NetRcMacDef -> Ordering
$c< :: NetRcMacDef -> NetRcMacDef -> Bool
< :: NetRcMacDef -> NetRcMacDef -> Bool
$c<= :: NetRcMacDef -> NetRcMacDef -> Bool
<= :: NetRcMacDef -> NetRcMacDef -> Bool
$c> :: NetRcMacDef -> NetRcMacDef -> Bool
> :: NetRcMacDef -> NetRcMacDef -> Bool
$c>= :: NetRcMacDef -> NetRcMacDef -> Bool
>= :: NetRcMacDef -> NetRcMacDef -> Bool
$cmax :: NetRcMacDef -> NetRcMacDef -> NetRcMacDef
max :: NetRcMacDef -> NetRcMacDef -> NetRcMacDef
$cmin :: NetRcMacDef -> NetRcMacDef -> NetRcMacDef
min :: NetRcMacDef -> NetRcMacDef -> NetRcMacDef
Ord, Int -> NetRcMacDef -> ShowS
[NetRcMacDef] -> ShowS
NetRcMacDef -> String
(Int -> NetRcMacDef -> ShowS)
-> (NetRcMacDef -> String)
-> ([NetRcMacDef] -> ShowS)
-> Show NetRcMacDef
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NetRcMacDef -> ShowS
showsPrec :: Int -> NetRcMacDef -> ShowS
$cshow :: NetRcMacDef -> String
show :: NetRcMacDef -> String
$cshowList :: [NetRcMacDef] -> ShowS
showList :: [NetRcMacDef] -> ShowS
Show, Typeable NetRcMacDef
Typeable NetRcMacDef =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> NetRcMacDef -> c NetRcMacDef)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NetRcMacDef)
-> (NetRcMacDef -> Constr)
-> (NetRcMacDef -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NetRcMacDef))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c NetRcMacDef))
-> ((forall b. Data b => b -> b) -> NetRcMacDef -> NetRcMacDef)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r)
-> (forall u. (forall d. Data d => d -> u) -> NetRcMacDef -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> NetRcMacDef -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef)
-> Data NetRcMacDef
NetRcMacDef -> Constr
NetRcMacDef -> DataType
(forall b. Data b => b -> b) -> NetRcMacDef -> NetRcMacDef
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> NetRcMacDef -> u
forall u. (forall d. Data d => d -> u) -> NetRcMacDef -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRcMacDef
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRcMacDef -> c NetRcMacDef
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRcMacDef)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NetRcMacDef)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRcMacDef -> c NetRcMacDef
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRcMacDef -> c NetRcMacDef
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRcMacDef
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRcMacDef
$ctoConstr :: NetRcMacDef -> Constr
toConstr :: NetRcMacDef -> Constr
$cdataTypeOf :: NetRcMacDef -> DataType
dataTypeOf :: NetRcMacDef -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRcMacDef)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRcMacDef)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NetRcMacDef)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NetRcMacDef)
$cgmapT :: (forall b. Data b => b -> b) -> NetRcMacDef -> NetRcMacDef
gmapT :: (forall b. Data b => b -> b) -> NetRcMacDef -> NetRcMacDef
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NetRcMacDef -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NetRcMacDef -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> NetRcMacDef -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NetRcMacDef -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NetRcMacDef -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRcMacDef -> m NetRcMacDef
Data, (forall x. NetRcMacDef -> Rep NetRcMacDef x)
-> (forall x. Rep NetRcMacDef x -> NetRcMacDef)
-> Generic NetRcMacDef
forall x. Rep NetRcMacDef x -> NetRcMacDef
forall x. NetRcMacDef -> Rep NetRcMacDef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NetRcMacDef -> Rep NetRcMacDef x
from :: forall x. NetRcMacDef -> Rep NetRcMacDef x
$cto :: forall x. Rep NetRcMacDef x -> NetRcMacDef
to :: forall x. Rep NetRcMacDef x -> NetRcMacDef
Generic)

instance NFData NetRcMacDef where rnf :: NetRcMacDef -> ()
rnf !NetRcMacDef
_ = ()

-- | Represents (semantic) contents of a @.netrc@ file
data NetRc = NetRc
    { NetRc -> [NetRcHost]
nrHosts  :: [NetRcHost]   -- ^ @machine@\/@default@ entries
                                --
                                -- __Note__: If it exists, the
                                -- @default@ entry ought to be the
                                -- last entry, otherwise it can cause
                                -- later entries to become invisible
                                -- for some implementations
                                -- (e.g. @ftp(1)@)

    , NetRc -> [NetRcMacDef]
nrMacros :: [NetRcMacDef] -- ^ Non-associated @macdef@ entries
                                --
                                -- __Note__: @macdef@ entries not
                                -- associated with host-entries are
                                -- invisible to some applications
                                -- (e.g. @ftp(1)@).
    } deriving (NetRc -> NetRc -> Bool
(NetRc -> NetRc -> Bool) -> (NetRc -> NetRc -> Bool) -> Eq NetRc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NetRc -> NetRc -> Bool
== :: NetRc -> NetRc -> Bool
$c/= :: NetRc -> NetRc -> Bool
/= :: NetRc -> NetRc -> Bool
Eq, Eq NetRc
Eq NetRc =>
(NetRc -> NetRc -> Ordering)
-> (NetRc -> NetRc -> Bool)
-> (NetRc -> NetRc -> Bool)
-> (NetRc -> NetRc -> Bool)
-> (NetRc -> NetRc -> Bool)
-> (NetRc -> NetRc -> NetRc)
-> (NetRc -> NetRc -> NetRc)
-> Ord NetRc
NetRc -> NetRc -> Bool
NetRc -> NetRc -> Ordering
NetRc -> NetRc -> NetRc
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
$ccompare :: NetRc -> NetRc -> Ordering
compare :: NetRc -> NetRc -> Ordering
$c< :: NetRc -> NetRc -> Bool
< :: NetRc -> NetRc -> Bool
$c<= :: NetRc -> NetRc -> Bool
<= :: NetRc -> NetRc -> Bool
$c> :: NetRc -> NetRc -> Bool
> :: NetRc -> NetRc -> Bool
$c>= :: NetRc -> NetRc -> Bool
>= :: NetRc -> NetRc -> Bool
$cmax :: NetRc -> NetRc -> NetRc
max :: NetRc -> NetRc -> NetRc
$cmin :: NetRc -> NetRc -> NetRc
min :: NetRc -> NetRc -> NetRc
Ord, Int -> NetRc -> ShowS
[NetRc] -> ShowS
NetRc -> String
(Int -> NetRc -> ShowS)
-> (NetRc -> String) -> ([NetRc] -> ShowS) -> Show NetRc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NetRc -> ShowS
showsPrec :: Int -> NetRc -> ShowS
$cshow :: NetRc -> String
show :: NetRc -> String
$cshowList :: [NetRc] -> ShowS
showList :: [NetRc] -> ShowS
Show, Typeable NetRc
Typeable NetRc =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> NetRc -> c NetRc)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NetRc)
-> (NetRc -> Constr)
-> (NetRc -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NetRc))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRc))
-> ((forall b. Data b => b -> b) -> NetRc -> NetRc)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r)
-> (forall u. (forall d. Data d => d -> u) -> NetRc -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> NetRc -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> NetRc -> m NetRc)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NetRc -> m NetRc)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NetRc -> m NetRc)
-> Data NetRc
NetRc -> Constr
NetRc -> DataType
(forall b. Data b => b -> b) -> NetRc -> NetRc
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> NetRc -> u
forall u. (forall d. Data d => d -> u) -> NetRc -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRc
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRc -> c NetRc
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRc)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRc)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRc -> c NetRc
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NetRc -> c NetRc
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRc
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NetRc
$ctoConstr :: NetRc -> Constr
toConstr :: NetRc -> Constr
$cdataTypeOf :: NetRc -> DataType
dataTypeOf :: NetRc -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRc)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NetRc)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRc)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NetRc)
$cgmapT :: (forall b. Data b => b -> b) -> NetRc -> NetRc
gmapT :: (forall b. Data b => b -> b) -> NetRc -> NetRc
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NetRc -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NetRc -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> NetRc -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NetRc -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NetRc -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NetRc -> m NetRc
Data, (forall x. NetRc -> Rep NetRc x)
-> (forall x. Rep NetRc x -> NetRc) -> Generic NetRc
forall x. Rep NetRc x -> NetRc
forall x. NetRc -> Rep NetRc x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NetRc -> Rep NetRc x
from :: forall x. NetRc -> Rep NetRc x
$cto :: forall x. Rep NetRc x -> NetRc
to :: forall x. Rep NetRc x -> NetRc
Generic)

instance NFData NetRc where
    rnf :: NetRc -> ()
rnf (NetRc [NetRcHost]
ms [NetRcMacDef]
ds) = [NetRcHost]
ms [NetRcHost] -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` [NetRcMacDef]
ds [NetRcMacDef] -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()

-- | Construct a 'ByteString' 'BB.Builder'
netRcToBuilder :: NetRc -> BB.Builder
netRcToBuilder :: NetRc -> Builder
netRcToBuilder (NetRc [NetRcHost]
ms [NetRcMacDef]
ds) =
    [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> ([Builder] -> [Builder]) -> [Builder] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
nl ([Builder] -> Builder) -> [Builder] -> Builder
forall a b. (a -> b) -> a -> b
$ (NetRcMacDef -> Builder) -> [NetRcMacDef] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map NetRcMacDef -> Builder
netRcMacDefToBuilder [NetRcMacDef]
ds [Builder] -> [Builder] -> [Builder]
forall a. Semigroup a => a -> a -> a
<> (NetRcHost -> Builder) -> [NetRcHost] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map NetRcHost -> Builder
netRcHostToBuilder [NetRcHost]
ms
  where
    netRcHostToBuilder :: NetRcHost -> Builder
netRcHostToBuilder (NetRcHost {[NetRcMacDef]
ByteString
nrhName :: NetRcHost -> ByteString
nrhLogin :: NetRcHost -> ByteString
nrhPassword :: NetRcHost -> ByteString
nrhAccount :: NetRcHost -> ByteString
nrhMacros :: NetRcHost -> [NetRcMacDef]
nrhName :: ByteString
nrhLogin :: ByteString
nrhPassword :: ByteString
nrhAccount :: ByteString
nrhMacros :: [NetRcMacDef]
..})
        = [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder) -> [Builder] -> Builder
forall a b. (a -> b) -> a -> b
$
          [ Builder
mline
          , ByteString -> ByteString -> Builder
prop ByteString
"login"    ByteString
nrhLogin
          , ByteString -> ByteString -> Builder
prop ByteString
"password" ByteString
nrhPassword
          , ByteString -> ByteString -> Builder
prop ByteString
"account"  ByteString
nrhAccount
          , Builder
nl
          ] [Builder] -> [Builder] -> [Builder]
forall a. Semigroup a => a -> a -> a
<> (Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
nl ([Builder] -> [Builder]) -> [Builder] -> [Builder]
forall a b. (a -> b) -> a -> b
$ (NetRcMacDef -> Builder) -> [NetRcMacDef] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map NetRcMacDef -> Builder
netRcMacDefToBuilder [NetRcMacDef]
nrhMacros)
      where
        mline :: Builder
mline | ByteString -> Bool
B.null ByteString
nrhName = ByteString -> Builder
BB.byteString ByteString
"default"
              | Bool
otherwise      = ByteString -> Builder
BB.byteString ByteString
"machine" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
spc Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BB.byteString ByteString
nrhName

        prop :: ByteString -> ByteString -> Builder
prop ByteString
lab ByteString
val | ByteString -> Bool
B.null ByteString
val = Builder
forall a. Monoid a => a
mempty
                     | Bool
otherwise  = Builder
spc Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BB.byteString ByteString
lab Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
spc Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BB.byteString ByteString
val

    netRcMacDefToBuilder :: NetRcMacDef -> Builder
netRcMacDefToBuilder (NetRcMacDef {ByteString
nrmName :: NetRcMacDef -> ByteString
nrmBody :: NetRcMacDef -> ByteString
nrmName :: ByteString
nrmBody :: ByteString
..})
        = ByteString -> Builder
BB.byteString ByteString
"macdef" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
spc Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BB.byteString ByteString
nrmName Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
          (if ByteString -> Bool
B.null ByteString
nrmBody then Builder
forall a. Monoid a => a
mempty else Builder
nl Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BB.byteString ByteString
nrmBody) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
          Builder
nl

    spc :: Builder
spc = Char -> Builder
BB.charUtf8 Char
' '
    nl :: Builder
nl  = Char -> Builder
BB.charUtf8 Char
'\n'

-- | Format 'NetRc' into a 'ByteString'
--
-- This is currently just a convenience wrapper around 'netRcToBuilder'
netRcToByteString :: NetRc -> ByteString
netRcToByteString :: NetRc -> ByteString
netRcToByteString = LazyByteString -> ByteString
LB.toStrict (LazyByteString -> ByteString)
-> (NetRc -> LazyByteString) -> NetRc -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BB.toLazyByteString (Builder -> LazyByteString)
-> (NetRc -> Builder) -> NetRc -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NetRc -> Builder
netRcToBuilder

-- | Convenience wrapper for 'netRcParsec' parser
--
-- This is basically just
--
-- @
-- 'parseNetRc' = 'P.parse' ('netRcParsec' <* 'P.eof')
-- @
--
-- This wrapper is mostly useful for avoiding to have to import Parsec
-- modules (and to build-depend explicitly on @parsec@).
--
parseNetRc :: P.SourceName -> ByteString -> Either P.ParseError NetRc
parseNetRc :: String -> ByteString -> Either ParseError NetRc
parseNetRc = Parsec ByteString () NetRc
-> String -> ByteString -> Either ParseError NetRc
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
P.parse (Parsec ByteString () NetRc
netRcParsec Parsec ByteString () NetRc
-> ParsecT ByteString () Identity () -> Parsec ByteString () NetRc
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT ByteString () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
P.eof)

-- | Reads and parses default @$HOME/.netrc@
--
-- Returns 'Nothing' if @$HOME@ variable undefined and/or if @.netrc@ if missing.
-- Throws standard IO exceptions in case of other filesystem-errors.
--
-- __Note__: This function performs no permission sanity-checking on
--           the @.netrc@ file
readUserNetRc :: IO (Maybe (Either P.ParseError NetRc))
readUserNetRc :: IO (Maybe (Either ParseError NetRc))
readUserNetRc = do
    mhome <- String -> IO (Maybe String)
lookupEnv String
"HOME"
    case mhome of
        Maybe String
Nothing -> Maybe (Either ParseError NetRc)
-> IO (Maybe (Either ParseError NetRc))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either ParseError NetRc)
forall a. Maybe a
Nothing
        Just String
"" -> Maybe (Either ParseError NetRc)
-> IO (Maybe (Either ParseError NetRc))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either ParseError NetRc)
forall a. Maybe a
Nothing
        Just String
ho -> do
            let fn :: String
fn = String
ho String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"/.netrc"
            ret <- IO ByteString -> IO (Either IOError ByteString)
forall a. IO a -> IO (Either IOError a)
tryIOError (String -> IO ByteString
B.readFile String
fn)
            case ret of
                Left IOError
e | IOError -> Bool
isDoesNotExistError IOError
e -> Maybe (Either ParseError NetRc)
-> IO (Maybe (Either ParseError NetRc))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either ParseError NetRc)
forall a. Maybe a
Nothing
                       | Bool
otherwise             -> IOError -> IO (Maybe (Either ParseError NetRc))
forall a. HasCallStack => IOError -> IO a
ioError IOError
e
                Right ByteString
b -> Maybe (Either ParseError NetRc)
-> IO (Maybe (Either ParseError NetRc))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Either ParseError NetRc)
 -> IO (Maybe (Either ParseError NetRc)))
-> Maybe (Either ParseError NetRc)
-> IO (Maybe (Either ParseError NetRc))
forall a b. (a -> b) -> a -> b
$! Either ParseError NetRc -> Maybe (Either ParseError NetRc)
forall a. a -> Maybe a
Just (Either ParseError NetRc -> Maybe (Either ParseError NetRc))
-> Either ParseError NetRc -> Maybe (Either ParseError NetRc)
forall a b. (a -> b) -> a -> b
$! String -> ByteString -> Either ParseError NetRc
parseNetRc String
fn ByteString
b

-- | "Text.Parsec.ByteString" 'P.Parser' for @.netrc@ grammar
netRcParsec :: P.Parser NetRc
netRcParsec :: Parsec ByteString () NetRc
netRcParsec = do
    entries <- ([NetRcHost] -> [NetRcMacDef] -> NetRc)
-> ([NetRcHost], [NetRcMacDef]) -> NetRc
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [NetRcHost] -> [NetRcMacDef] -> NetRc
NetRc (([NetRcHost], [NetRcMacDef]) -> NetRc)
-> ([Either NetRcHost NetRcMacDef] -> ([NetRcHost], [NetRcMacDef]))
-> [Either NetRcHost NetRcMacDef]
-> NetRc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([NetRcHost], [NetRcMacDef])] -> ([NetRcHost], [NetRcMacDef])
normEnts ([([NetRcHost], [NetRcMacDef])] -> ([NetRcHost], [NetRcMacDef]))
-> ([Either NetRcHost NetRcMacDef]
    -> [([NetRcHost], [NetRcMacDef])])
-> [Either NetRcHost NetRcMacDef]
-> ([NetRcHost], [NetRcMacDef])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Either NetRcHost NetRcMacDef] -> [([NetRcHost], [NetRcMacDef])]
forall l r. [Either l r] -> [([l], [r])]
splitEithers ([Either NetRcHost NetRcMacDef] -> NetRc)
-> ParsecT ByteString () Identity [Either NetRcHost NetRcMacDef]
-> Parsec ByteString () NetRc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT ByteString () Identity ()
wsOrComments0 ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity [Either NetRcHost NetRcMacDef]
-> ParsecT ByteString () Identity [Either NetRcHost NetRcMacDef]
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity [Either NetRcHost NetRcMacDef]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
P.sepEndBy ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
netrcEnt ParsecT ByteString () Identity ()
wsOrComments1)

    return entries
  where
    wsOrComments0 :: ParsecT ByteString () Identity ()
wsOrComments0 = ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
P.skipMany ParsecT ByteString () Identity ()
comment ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
P.skipMany (ParsecT ByteString () Identity ()
wsChars1 ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
P.skipMany ParsecT ByteString () Identity ()
comment)
    wsOrComments1 :: ParsecT ByteString () Identity ()
wsOrComments1 = ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
P.skipMany1 (ParsecT ByteString () Identity ()
wsChars1 ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
P.skipMany ParsecT ByteString () Identity ()
comment)

    netrcEnt :: ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
netrcEnt = (NetRcHost -> Either NetRcHost NetRcMacDef
forall a b. a -> Either a b
Left (NetRcHost -> Either NetRcHost NetRcMacDef)
-> ParsecT ByteString () Identity NetRcHost
-> ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ByteString () Identity NetRcHost
hostEnt) ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
-> ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
-> ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
forall a.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (NetRcMacDef -> Either NetRcHost NetRcMacDef
forall a b. b -> Either a b
Right (NetRcMacDef -> Either NetRcHost NetRcMacDef)
-> ParsecT ByteString () Identity NetRcMacDef
-> ParsecT ByteString () Identity (Either NetRcHost NetRcMacDef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ByteString () Identity NetRcMacDef
macDefEnt)

    normEnts :: [([NetRcHost], [NetRcMacDef])] -> ([NetRcHost], [NetRcMacDef])
normEnts [] = ([], [])
    normEnts (([], [NetRcMacDef]
ms):[([NetRcHost], [NetRcMacDef])]
es) = ([([NetRcHost], [NetRcMacDef])] -> [NetRcHost]
normEnts' [([NetRcHost], [NetRcMacDef])]
es, [NetRcMacDef]
ms)
    normEnts [([NetRcHost], [NetRcMacDef])]
es = ([([NetRcHost], [NetRcMacDef])] -> [NetRcHost]
normEnts' [([NetRcHost], [NetRcMacDef])]
es, [])

    normEnts' :: [([NetRcHost],[NetRcMacDef])] -> [NetRcHost]
    normEnts' :: [([NetRcHost], [NetRcMacDef])] -> [NetRcHost]
normEnts' [] = []
    normEnts' (([], [NetRcMacDef]
_):[([NetRcHost], [NetRcMacDef])]
_) = String -> [NetRcHost]
forall a. HasCallStack => String -> a
error String
"netRcParsec internal error"
    normEnts' (([NetRcHost]
hs, [NetRcMacDef]
ms):[([NetRcHost], [NetRcMacDef])]
es) = [NetRcHost] -> [NetRcHost]
forall a. HasCallStack => [a] -> [a]
init [NetRcHost]
hs [NetRcHost] -> [NetRcHost] -> [NetRcHost]
forall a. [a] -> [a] -> [a]
++ (([NetRcHost] -> NetRcHost
forall a. HasCallStack => [a] -> a
last [NetRcHost]
hs) { nrhMacros = ms } NetRcHost -> [NetRcHost] -> [NetRcHost]
forall a. a -> [a] -> [a]
: [([NetRcHost], [NetRcMacDef])] -> [NetRcHost]
normEnts' [([NetRcHost], [NetRcMacDef])]
es)

macDefEnt :: P.Parser NetRcMacDef
macDefEnt :: ParsecT ByteString () Identity NetRcMacDef
macDefEnt = do
    ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT ByteString () Identity String
 -> ParsecT ByteString () Identity ())
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ()
forall a b. (a -> b) -> a -> b
$ ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT ByteString () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"macdef")
    ParsecT ByteString () Identity ()
wsChars1
    n <- Parser ByteString
tok Parser ByteString -> String -> Parser ByteString
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"macdef-name"
    P.skipMany (P.oneOf "\t ")
    lf
    bodyLines <- P.sepEndBy neline lf
    return $! NetRcMacDef n (BC.pack $ unlines bodyLines)
  where
    neline :: ParsecT ByteString u Identity String
neline = ParsecT ByteString u Identity Char
-> ParsecT ByteString u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many1 (String -> ParsecT ByteString u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"\n")

hostEnt :: P.Parser NetRcHost
hostEnt :: ParsecT ByteString () Identity NetRcHost
hostEnt = do
    nam <- Parser ByteString
mac Parser ByteString -> Parser ByteString -> Parser ByteString
forall a.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString
forall {u}. ParsecT ByteString u Identity ByteString
def
    ps <- P.many (P.try (wsChars1 *> pval))
    return $! foldl' setFld (NetRcHost nam "" "" "" []) ps
  where
    def :: ParsecT ByteString u Identity ByteString
def = ParsecT ByteString u Identity String
-> ParsecT ByteString u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT ByteString u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"default") ParsecT ByteString u Identity String
-> ParsecT ByteString u Identity ByteString
-> ParsecT ByteString u Identity ByteString
forall a b.
ParsecT ByteString u Identity a
-> ParsecT ByteString u Identity b
-> ParsecT ByteString u Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ByteString -> ParsecT ByteString u Identity ByteString
forall a. a -> ParsecT ByteString u Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
""

    mac :: Parser ByteString
mac = do
        ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT ByteString () Identity String
 -> ParsecT ByteString () Identity ())
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT ByteString () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"machine")
        ParsecT ByteString () Identity ()
wsChars1
        Parser ByteString
tok Parser ByteString -> String -> Parser ByteString
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"hostname"

    -- pval := ((account|username|password) WS+ <value>)
    pval :: ParsecT ByteString () Identity PVal
pval = String
-> (ByteString -> PVal) -> ParsecT ByteString () Identity PVal
forall {b}.
String -> (ByteString -> b) -> ParsecT ByteString () Identity b
hlp String
"login"    ByteString -> PVal
PValLogin   ParsecT ByteString () Identity PVal
-> ParsecT ByteString () Identity PVal
-> ParsecT ByteString () Identity PVal
forall a.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
           String
-> (ByteString -> PVal) -> ParsecT ByteString () Identity PVal
forall {b}.
String -> (ByteString -> b) -> ParsecT ByteString () Identity b
hlp String
"account"  ByteString -> PVal
PValAccount ParsecT ByteString () Identity PVal
-> ParsecT ByteString () Identity PVal
-> ParsecT ByteString () Identity PVal
forall a.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
           String
-> (ByteString -> PVal) -> ParsecT ByteString () Identity PVal
forall {b}.
String -> (ByteString -> b) -> ParsecT ByteString () Identity b
hlp String
"password" ByteString -> PVal
PValPassword
      where
        hlp :: String -> (ByteString -> b) -> ParsecT ByteString () Identity b
hlp String
tnam ByteString -> b
cons = ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT ByteString () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
tnam) ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT ByteString () Identity ()
wsChars1 ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
                        (ByteString -> b
cons (ByteString -> b)
-> Parser ByteString -> ParsecT ByteString () Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
tok ParsecT ByteString () Identity b
-> String -> ParsecT ByteString () Identity b
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> (String
tnam String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"-value"))

    setFld :: NetRcHost -> PVal -> NetRcHost
setFld NetRcHost
n (PValLogin    ByteString
v) = NetRcHost
n { nrhLogin    = v }
    setFld NetRcHost
n (PValAccount  ByteString
v) = NetRcHost
n { nrhAccount  = v }
    setFld NetRcHost
n (PValPassword ByteString
v) = NetRcHost
n { nrhPassword = v }

tok :: P.Parser ByteString
tok :: Parser ByteString
tok = String -> ByteString
BC.pack (String -> ByteString)
-> ParsecT ByteString () Identity String -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many1 ParsecT ByteString () Identity Char
notWsChar Parser ByteString -> String -> Parser ByteString
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"token"

data PVal = PValLogin    !ByteString
          | PValAccount  !ByteString
          | PValPassword !ByteString
          deriving Int -> PVal -> ShowS
[PVal] -> ShowS
PVal -> String
(Int -> PVal -> ShowS)
-> (PVal -> String) -> ([PVal] -> ShowS) -> Show PVal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PVal -> ShowS
showsPrec :: Int -> PVal -> ShowS
$cshow :: PVal -> String
show :: PVal -> String
$cshowList :: [PVal] -> ShowS
showList :: [PVal] -> ShowS
Show

lf, wsChar, wsChars1 :: P.Parser ()
lf :: ParsecT ByteString () Identity ()
lf       = ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Char -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'\n') ParsecT ByteString () Identity ()
-> String -> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"line-feed"
wsChar :: ParsecT ByteString () Identity ()
wsChar   = ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (String -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"\t \n")
wsChars1 :: ParsecT ByteString () Identity ()
wsChars1 = ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
P.skipMany1 ParsecT ByteString () Identity ()
wsChar

-- | Any 'Char' not parsed by 'wsChar'
notWsChar :: P.Parser Char
notWsChar :: ParsecT ByteString () Identity Char
notWsChar = String -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"\t \n"

-- | Comments (where allowed) go till rest of line
comment :: P.Parser ()
comment :: ParsecT ByteString () Identity ()
comment = (Char -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'#' ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT ByteString () Identity ()
skipToEol) ParsecT ByteString () Identity ()
-> String -> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"comment"

-- | Consume/skip rest of line
skipToEol :: P.Parser ()
skipToEol :: ParsecT ByteString () Identity ()
skipToEol = ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
P.skipMany ParsecT ByteString () Identity Char
forall {u}. ParsecT ByteString u Identity Char
notlf ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a b.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity b
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (ParsecT ByteString () Identity ()
lf ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
-> ParsecT ByteString () Identity ()
forall a.
ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
-> ParsecT ByteString () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT ByteString () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
P.eof)
  where
    notlf :: ParsecT ByteString u Identity Char
notlf = String -> ParsecT ByteString u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"\n"

-- | Regroup lst of 'Either's into pair of lists
splitEithers :: [Either l r] -> [([l], [r])]
splitEithers :: forall l r. [Either l r] -> [([l], [r])]
splitEithers = [Either l r] -> [([l], [r])]
forall l r. [Either l r] -> [([l], [r])]
goL
  where
    goL :: [Either a a] -> [([a], [a])]
goL []    = []
    goL [Either a a]
es    = let ([Either a a]
pfx,[Either a a]
es') = (Either a a -> Bool)
-> [Either a a] -> ([Either a a], [Either a a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Either a a -> Bool
forall {a} {b}. Either a b -> Bool
isLeft  [Either a a]
es in [Either a a] -> [a] -> [([a], [a])]
goR [Either a a]
es' ([Either a a] -> [a]
forall a b. [Either a b] -> [a]
lefts [Either a a]
pfx)

    goR :: [Either a a] -> [a] -> [([a], [a])]
goR [] [a]
ls = [([a]
ls,[])]
    goR [Either a a]
es [a]
ls = let ([Either a a]
pfx,[Either a a]
es') = (Either a a -> Bool)
-> [Either a a] -> ([Either a a], [Either a a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Either a a -> Bool
forall {a} {b}. Either a b -> Bool
isRight [Either a a]
es in ([a]
ls,[Either a a] -> [a]
forall a b. [Either a b] -> [b]
rights [Either a a]
pfx) ([a], [a]) -> [([a], [a])] -> [([a], [a])]
forall a. a -> [a] -> [a]
: [Either a a] -> [([a], [a])]
goL [Either a a]
es'

    isLeft :: Either a b -> Bool
isLeft (Left a
_)  = Bool
True
    isLeft (Right b
_) = Bool
False

    isRight :: Either a b -> Bool
isRight = Bool -> Bool
not (Bool -> Bool) -> (Either a b -> Bool) -> Either a b -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either a b -> Bool
forall {a} {b}. Either a b -> Bool
isLeft