# Control.ST.File

interface File

  Description of state transition operations on a file.

  +------------+-------------+----------------+----------------+----------------+
  | Operation | State in | Mode in | State out | Mode out |
  +------------+-------------+----------------+----------------+----------------+
  | open | - | - | file handle | input paramater|
  | close | file handle | any | - | - |
  | eof | file handle | ValidModeRead | file handle | ValidModeRead |
  | flush | file handle | any | file handle | unchanged |
  | readLine | file handle | ValidModeRead | file handle | ValidModeRead |
  | readChar | file handle | ValidModeRead | file handle | ValidModeRead |
  | readFile | - | - | - | - |
  | writeString| file handle | ValidModeWrite | file handle | ValidModeWrite |
  | writeLine | file handle | ValidModeWrite | file handle | ValidModeWrite |
  | writeFile | - | - | - | - |
  +------------+-------------+----------------+----------------+----------------+

  FileHandleI : File m => Mode -> Type
  open : File m => (fname : String) -> (mode : Mode) -> ST m (Either FileError Var) [addIfRight (FileHandleI mode)]

    Open a file.

  close : File m => (fileHandle : Var) -> ST m () [remove fileHandle (FileHandleI mode)]

    Close a file.

  eof : File m => (fileHandle : Var) -> {auto prf : ValidModeRead mode} -> ST m Bool [fileHandle ::: FileHandleI mode]

    Have we reached the end of the file.

  flush : File m => (fileHandle : Var) -> ST m () [fileHandle ::: FileHandleI mode]

    Flush

  readLine : File m => (fileHandle : Var) -> {auto prf : ValidModeRead mode} -> ST m (Either FileError String) [fileHandle ::: FileHandleI mode]

    Read a complete line.

  readChar : File m => (fileHandle : Var) -> {auto prf : ValidModeRead mode} -> ST m (Either FileError Char) [fileHandle ::: FileHandleI mode]

    Read a `Char`.

  readFile : File m => (fileName : String) -> ST m (Either FileError String) []

    Read the contents of a file into a string.

    This checks the size of
    the file before beginning to read, and only reads that many bytes,
    to ensure that it remains a total function if the file is appended
    to while being read.

    Returns an error if fname is not a normal file.

  writeString : File m => (fileHandle : Var) -> (string : String) -> {auto prf : ValidModeWrite mode} -> ST m (Either FileError ()) [fileHandle ::: FileHandleI mode]

    Write a complete line to the file.

  writeLine : File m => (fileHandle : Var) -> (string : String) -> {auto prf : ValidModeWrite mode} -> ST m (Either FileError ()) [fileHandle ::: FileHandleI mode]

    Write a complete line to the file.

  writeFile : File m => (fname : String) -> (string : String) -> ST m (Either FileError ()) []

    Create a file and write contents to the file.

data FileHandle : (mode : Mode) -> Type

  The file handle which will be used as a State Transition
  resource in the `IO` and `IOExcept` implementations of `File`.

  mode

    The `Mode` that the handle was generated under.

  FH : File -> FileHandle mode
data ValidModeRead : Mode -> Type

  A record of the file modes that can read from a file.

  VMRRead : ValidModeRead Read
  VMRReadW : ValidModeRead ReadWrite
  VMRReadWT : ValidModeRead ReadWriteTruncate
  VMRReadA : ValidModeRead ReadAppend
data ValidModeWrite : Mode -> Type

  A record of the file modes that can write from a file.

  VMWWrite : ValidModeWrite WriteTruncate
  VMWAppend : ValidModeWrite Append
  VMWReadW : ValidModeWrite ReadWrite
  VMWReadWT : ValidModeWrite ReadWriteTruncate