{-# 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, foldl')
import           Data.Monoid
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,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,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,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
#if MIN_VERSION_bytestring(0,10,0)
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
#else
netRcToByteString = B.concat . LB.toChunks . BB.toLazyByteString . netRcToBuilder
#endif


-- | 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. 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
#if !(MIN_VERSION_base(4,6,0))
  where
    lookupEnv k = lookup k <$> getEnvironment
#endif

-- | "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