-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Use RawFilePath instead of FilePath
--   
--   Please see README.md
@package rawfilepath
@version 0.2.4


-- | Welcome to <tt>RawFilePath.Process</tt>, a small part of the Haskell
--   community's effort to purge <a>String</a> for the Greater Good.
--   
--   With this module, you can create (and interact with) sub-processes
--   without the encoding problem of <a>String</a>. The command and its
--   arguments, all <a>ByteString</a>s, never get converted from/to
--   <a>String</a> internally on its way to the actual syscall. It also
--   avoids the time/space waste of <a>String</a>.
--   
--   The interface, unlike the original <tt>process</tt> package, uses
--   types to prevent unnecessary runtime errors when obtaining
--   <a>Handle</a>s. This is inspired by the <tt>typed-process</tt> package
--   which is awesome, although this module is much simpler; it doesn't
--   introduce any new requirement of language extension or library package
--   (for the sake of portability).
--   
--   <a>Handle</a> (accessible with <a>processStdin</a>,
--   <a>processStdout</a>, and <a>processStderr</a>) is what you can use to
--   interact with the sub-process. For example, use <a>hGetContents</a>
--   from <a>Data.ByteString</a> to read from a <a>Handle</a> as a
--   <a>ByteString</a>.
--   
--   <h2>Example</h2>
--   
--   <pre>
--   {-# language OverloadedStrings #-}
--   
--   import RawFilePath.Process
--   import qualified Data.ByteString as B
--   
--   main :: IO ()
--   main = do
--       p &lt;- <a>startProcess</a> $ <a>proc</a> "echo" ["hello"]
--           `setStdout` <a>CreatePipe</a>
--       result &lt;- B.hGetContents (<a>processStdout</a> p)
--       _ &lt;- <a>waitForProcess</a> p
--   
--       print (result == "hello\n")
--   </pre>
module RawFilePath.Process

-- | A literal POSIX file path
type RawFilePath = ByteString

-- | The process configuration that is needed for creating new processes.
--   Use <a>proc</a> to make one.
data ProcessConf stdin stdout stderr

-- | Create a process configuration with the default settings.
proc :: RawFilePath -> [ByteString] -> ProcessConf Inherit Inherit Inherit

-- | The class of types that determine the standard stream of a
--   sub-process. You can decide how to initialize the standard streams
--   (stdin, stdout, and stderr) of a sub-process with the instances of
--   this class.
class StreamType c where mbFd = undefined willCreateHandle = undefined

-- | Create a new pipe for the stream. You get a new <a>Handle</a>.
data CreatePipe
CreatePipe :: CreatePipe

-- | Inherit the parent (current) process handle. The child will share the
--   stream. For example, if the child writes anything to stdout, it will
--   all go to the parent's stdout.
data Inherit
Inherit :: Inherit

-- | No stream handle will be passed. Use when you don't want to
--   communicate with a stream. For example, to run something silently.
data NoStream
NoStream :: NoStream

-- | Use the supplied <a>Handle</a>.
data UseHandle
UseHandle :: Handle -> UseHandle

-- | Control how the standard input of the process will be initialized.
setStdin :: (StreamType newStdin) => ProcessConf oldStdin stdout stderr -> newStdin -> ProcessConf newStdin stdout stderr
infixl 4 `setStdin`

-- | Control how the standard output of the process will be initialized.
setStdout :: (StreamType newStdout) => ProcessConf stdin oldStdout stderr -> newStdout -> ProcessConf stdin newStdout stderr
infixl 4 `setStdout`

-- | Control how the standard error of the process will be initialized.
setStderr :: (StreamType newStderr) => ProcessConf stdin stdout oldStderr -> newStderr -> ProcessConf stdin stdout newStderr
infixl 4 `setStderr`

-- | The process type. The three type variables denote how its standard
--   streams were initialized.
data Process stdin stdout stderr

-- | Start a new sub-process with the given configuration.
startProcess :: (StreamType stdin, StreamType stdout, StreamType stderr) => ProcessConf stdin stdout stderr -> IO (Process stdin stdout stderr)

-- | Take a process and return its standard input handle.
processStdin :: Process CreatePipe stdout stderr -> Handle

-- | Take a process and return its standard output handle.
processStdout :: Process stdin CreatePipe stderr -> Handle

-- | Take a process and return its standard error handle.
processStderr :: Process stdin stdout CreatePipe -> Handle

-- | Stop a sub-process. For now it simply calls <a>terminateProcess</a>
--   and then <a>waitForProcess</a>.
stopProcess :: Process stdin stdout stderr -> IO ExitCode

-- | Terminate a sub-process by sending SIGTERM to it.
terminateProcess :: Process stdin stdout stderr -> IO ()

-- | Wait (block) for a sub-process to exit and obtain its exit code.
waitForProcess :: Process stdin stdout stderr -> IO ExitCode

-- | Create a new process with the given configuration, and wait for it to
--   finish.
callProcess :: ProcessConf stdin stdout stderr -> IO ExitCode

-- | Fork an external process, read its standard output and standard error
--   strictly, blocking until the process terminates, and return them with
--   the process exit code.
readProcessWithExitCode :: ProcessConf stdin stdout stderr -> IO (ExitCode, ByteString, ByteString)


-- | This is the module for the <a>RawFilePath</a> version of functions in
--   the <tt>directory</tt> package.
module RawFilePath.Directory

-- | A literal POSIX file path
type RawFilePath = ByteString

-- | Test whether the given path points to an existing filesystem object.
--   If the user lacks necessary permissions to search the parent
--   directories, this function may return false even if the file does
--   actually exist.
doesPathExist :: RawFilePath -> IO Bool

-- | Return <a>True</a> if the argument file exists and is not a directory,
--   and <a>False</a> otherwise.
doesFileExist :: RawFilePath -> IO Bool

-- | Return <a>True</a> if the argument file exists and is either a
--   directory or a symbolic link to a directory, and <a>False</a>
--   otherwise.
doesDirectoryExist :: RawFilePath -> IO Bool

-- | Returns the current user's home directory. More specifically, the
--   value of the <tt>HOME</tt> environment variable.
--   
--   The directory returned is expected to be writable by the current user,
--   but note that it isn't generally considered good practice to store
--   application-specific data here; use <tt>getXdgDirectory</tt> or
--   <tt>getAppUserDataDirectory</tt> instead.
--   
--   The operation may fail with:
--   
--   <ul>
--   <li><a>UnsupportedOperation</a> The operating system has no notion of
--   home directory.</li>
--   <li><a>isDoesNotExistError</a> The home directory for the current user
--   does not exist, or cannot be found.</li>
--   </ul>
getHomeDirectory :: IO (Maybe RawFilePath)

-- | Return the current directory for temporary files. It first returns the
--   value of the <tt>TMPDIR</tt> environment variable or "/tmp" if the
--   variable isn't defined.
getTemporaryDirectory :: IO ByteString

-- | Get a list of files in the specified directory, excluding "." and ".."
--   
--   <pre>
--   ghci&gt; listDirectory "/"
--   ["home","sys","var","opt","lib64","sbin","usr","srv","dev","lost+found","bin","tmp","run","root","boot","proc","etc","lib"]
--   </pre>
listDirectory :: RawFilePath -> IO [RawFilePath]

-- | Get a list of files in the specified directory, including "." and ".."
--   
--   <pre>
--   ghci&gt; getDirectoryFiles "/"
--   ["home","sys","var","opt","..","lib64","sbin","usr","srv","dev","lost+found","mnt","bin","tmp","run","root","boot",".","proc","etc","lib"]
--   </pre>
getDirectoryFiles :: RawFilePath -> IO [RawFilePath]

-- | Recursively get all files in all subdirectories of the specified
--   directory.
--   
--   <pre>
--   *System.RawFilePath&gt; getDirectoryFilesRecursive "src"
--   ["src/System/RawFilePath.hs"]
--   </pre>
getDirectoryFilesRecursive :: RawFilePath -> IO [RawFilePath]

-- | Create a new directory.
--   
--   <pre>
--   ghci&gt; createDirectory "/tmp/mydir"
--   ghci&gt; getDirectoryFiles "/tmp/mydir"
--   [".",".."]
--   ghci&gt; createDirectory "/tmp/mydir/anotherdir"
--   ghci&gt; getDirectoryFiles "/tmp/mydir"
--   [".","..","anotherdir"]
--   </pre>
createDirectory :: RawFilePath -> IO ()

-- | Create a new directory if it does not already exist. If the first
--   argument is <a>True</a> the function will also create all parent
--   directories when they are missing.
createDirectoryIfMissing :: Bool -> RawFilePath -> IO ()

-- | Remove a file. This function internally calls <tt>unlink</tt>. If the
--   file does not exist, an exception is thrown.
removeFile :: RawFilePath -> IO ()

-- | A function that "tries" to remove a file. If the file does not exist,
--   nothing happens.
tryRemoveFile :: RawFilePath -> IO ()

-- | Remove a directory. The target directory needs to be empty; Otherwise
--   an exception will be thrown.
removeDirectory :: RawFilePath -> IO ()

-- | Remove an existing directory <i>dir</i> together with its contents and
--   subdirectories. Within this directory, symbolic links are removed
--   without affecting their targets.
removeDirectoryRecursive :: RawFilePath -> IO ()


-- | Welcome to <tt>RawFilePath</tt>, a small part of the Haskell
--   community's effort to purge <a>String</a> for the Greater Good.
--   
--   With this package, you can interact with the Unix system without the
--   file path encoding issue or the <a>String</a> ↔ <a>ByteString</a>
--   conversion overhead.
--   
--   <h2>Rationale</h2>
--   
--   Traditional <a>String</a> is notorious:
--   
--   <ul>
--   <li>24 bytes (three words) required for one character (the List
--   constructor, the actual Char value, and the pointer to the next List
--   constructor). 24x memory consumption.</li>
--   <li>Heap fragmentation causing malloc/free overhead</li>
--   <li>A lot of pointer chasing for reading, devastating the cache hit
--   rate</li>
--   <li>A lot of pointer chasing plus a lot of heap object allocation for
--   manipulation (appending, slicing, etc.)</li>
--   <li>Completely unnecessary but mandatory conversions and memory
--   allocation when the data is sent to or received from the outside
--   world</li>
--   </ul>
--   
--   <a>String</a> has another problematic nature to serve as a file path
--   data type: Encoding blindness. All functions that return
--   <a>FilePath</a> would actually take a series of bytes returned by a
--   syscall and somehow magically "decode" it into a <a>String</a> which
--   is surprising because no encoding information was given. Of course
--   there is no magic and it's an abject fail. <a>FilePath</a> just
--   wouldn't work.
--   
--   <h2>Usage</h2>
--   
--   This is the top-level module that re-exports the sub-modules.
--   Therefore, you can
--   
--   <pre>
--   import RawFilePath
--   </pre>
--   
--   to import all functions.
module RawFilePath

-- | A literal POSIX file path
type RawFilePath = ByteString


-- | A drop-in replacement of <tt>Data.ByteString</tt> from the
--   <tt>bytestring</tt> package that provides file I/O functions with
--   <a>RawFilePath</a> instead of <a>FilePath</a>.
module Data.ByteString.RawFilePath

-- | A literal POSIX file path
type RawFilePath = ByteString

-- | Read an entire file at the <a>RawFilePath</a> strictly into a
--   <a>ByteString</a>.
readFile :: RawFilePath -> IO ByteString

-- | Write a <a>ByteString</a> to a file at the <a>RawFilePath</a>.
writeFile :: RawFilePath -> ByteString -> IO ()

-- | Append a <a>ByteString</a> to a file at the <a>RawFilePath</a>.
appendFile :: RawFilePath -> ByteString -> IO ()

-- | Acquire a file handle and perform an I/O action. The file will be
--   closed on exit or when this I/O action throws an exception.
withFile :: RawFilePath -> IOMode -> (Handle -> IO r) -> IO r
