fs-sim-0.3.1.0: Simulated file systems
Safe HaskellSafe-Inferred
LanguageHaskell2010

System.FS.Sim.MockFS

Description

Mock file system implementation

Intended for qualified import

import           System.FS.Sim.MockFS (MockFS)
import qualified System.FS.Sim.MockFS as Mock
Synopsis

Documentation

handleIsOpen :: MockFS -> HandleMock -> Bool #

Return True iff the handle is open.

Throws an exception if the handle is unknown.

numOpenHandles :: MockFS -> Int #

Number of open handles

pretty :: MockFS -> String #

Renders the MockFS in a human-readable fashion.

Debugging

dumpState :: CanSimFS m => m String #

Operations on files

hClose :: CanSimFS m => Handle' -> m () #

Mock implementation of hClose

hGetSize :: CanSimFS m => Handle' -> m Word64 #

Get file size

NOTE: In the mock implementation this is thread safe, because there can be only one writer, so concurrent threads cannot change the size of the file.

hGetSome :: CanSimFS m => Handle' -> Word64 -> m ByteString #

Get bytes from handle

NOTE: Unlike real I/O, we disallow hGetSome on a handle in append mode.

hGetSomeAt :: CanSimFS m => Handle' -> Word64 -> AbsOffset -> m ByteString #

Thread safe version of hGetSome, which doesn't modify or read the file offset.

hIsOpen :: CanSimFS m => Handle' -> m Bool #

Mock implementation of hIsOpen

hOpen :: CanSimFS m => FsPath -> OpenMode -> m Handle' #

Mock implementation of hOpen.

NOTE: Differences from Posix:

  • We do not support opening directories.
  • We do not support more than one concurrent writer (we do however allow a writer and multiple concurrent readers)
  • We do not support create file on ReadMode.

hPutSome :: CanSimFS m => Handle' -> ByteString -> m Word64 #

hSeek :: CanSimFS m => Handle' -> SeekMode -> Int64 -> m () #

Mock implementation of hSeek

NOTE: This is more restricted than the IO version, because seek has some odd properties:

  • We do not allow seeking at all on files in append mode
  • We do not allow seeking past the end of the file (this means that when using SeekFromEnd, the only valid offset is 0)
  • We do not return the new file offset

hTruncate :: CanSimFS m => Handle' -> Word64 -> m () #

Truncate a file

NOTE: Differences from Posix:

  • Although this corresponds to Posix ftruncate, this can only be used to make files smaller, not larger.
  • We only support this in append mode. The reason is that Posix ftruncate does not modify the file offset, and adds padding with zeroes on subsequent writes. This is however not behaviour we want to emulate. In append mode however the Posix file offset is not used (and we don't even record it at all), appends always happen at the end of the file.

Operations on directories

createDirectory :: CanSimFS m => FsPath -> m () #

createDirectoryIfMissing :: CanSimFS m => Bool -> FsPath -> m () #

doesDirectoryExist :: CanSimFS m => FsPath -> m Bool #

Check if directory exists

It seems real I/O maps what would be "inapproriate device" errors to False.

doesFileExist :: CanSimFS m => FsPath -> m Bool #

Check if file exists

See comments for doesDirectoryExist.

listDirectory :: CanSimFS m => FsPath -> m (Set String) #

removeDirectoryRecursive :: CanSimFS m => FsPath -> m () #

Remove a directory and its contents

Same limitations as removeFile.

removeFile :: CanSimFS m => FsPath -> m () #

Remove a file

The behaviour of unlink is to remove the file after all open file handles that refer to it are closed. The open file handles referring to the file can still be used to write/read to/from, while at the same time, the file is invisible for all other operations.

We do not implement this behaviour and consider this a limitation of the mock file system, and throw an error when removing a file that still has open file handles to it.

In the state machine tests, removing the root directory may cause the IO implementation to throw an FsInsufficientPermissions error, depending on the permissions of the temporary directory used to run the tests in. In theory it should throw a FsResourceInappropriateType error. To avoid this mismatch during testing, we also consider removing the root folder a limitation of the mock file system.

renameFile :: CanSimFS m => FsPath -> FsPath -> m () #

Exported for the benefit of tests only

type Files = FsTree ByteString #

We store the files as an FsTree of the file contents

opaque

data ClosedHandleState #

Instances

Instances details
Generic ClosedHandleState # 
Instance details

Defined in System.FS.Sim.MockFS

Associated Types

type Rep ClosedHandleState :: Type -> Type #

Show ClosedHandleState # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep ClosedHandleState # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep ClosedHandleState = D1 ('MetaData "ClosedHandleState" "System.FS.Sim.MockFS" "fs-sim-0.3.1.0-c0737daea019b4a86c2a751c72ae5b30966c50b66597c67533589e92aee29ad8" 'False) (C1 ('MetaCons "ClosedHandle" 'PrefixI 'True) (S1 ('MetaSel ('Just "closedFilePath") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 FsPath)))

data FilePtr #

File pointer

This is purely an internal abstraction.

Instances

Instances details
Generic FilePtr # 
Instance details

Defined in System.FS.Sim.MockFS

Associated Types

type Rep FilePtr :: Type -> Type #

Methods

from :: FilePtr -> Rep FilePtr x #

to :: Rep FilePtr x -> FilePtr #

Show FilePtr # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep FilePtr # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep FilePtr = D1 ('MetaData "FilePtr" "System.FS.Sim.MockFS" "fs-sim-0.3.1.0-c0737daea019b4a86c2a751c72ae5b30966c50b66597c67533589e92aee29ad8" 'False) (C1 ('MetaCons "RW" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Word64))) :+: C1 ('MetaCons "Append" 'PrefixI 'False) (U1 :: Type -> Type))

data HandleState #

Mock handle internal state

Instances

Instances details
Generic HandleState # 
Instance details

Defined in System.FS.Sim.MockFS

Associated Types

type Rep HandleState :: Type -> Type #

Show HandleState # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep HandleState # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep HandleState = D1 ('MetaData "HandleState" "System.FS.Sim.MockFS" "fs-sim-0.3.1.0-c0737daea019b4a86c2a751c72ae5b30966c50b66597c67533589e92aee29ad8" 'False) (C1 ('MetaCons "HandleOpen" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 OpenHandleState)) :+: C1 ('MetaCons "HandleClosed" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ClosedHandleState)))

data OpenHandleState #

Instances

Instances details
Generic OpenHandleState # 
Instance details

Defined in System.FS.Sim.MockFS

Associated Types

type Rep OpenHandleState :: Type -> Type #

Show OpenHandleState # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep OpenHandleState # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep OpenHandleState = D1 ('MetaData "OpenHandleState" "System.FS.Sim.MockFS" "fs-sim-0.3.1.0-c0737daea019b4a86c2a751c72ae5b30966c50b66597c67533589e92aee29ad8" 'False) (C1 ('MetaCons "OpenHandle" 'PrefixI 'True) (S1 ('MetaSel ('Just "openFilePath") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 FsPath) :*: S1 ('MetaSel ('Just "openPtr") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 FilePtr)))

opaque

data HandleMock #

A mock handle to a file on disk.

This is only meaningful when interpreted against a MockFS.

Instances

Instances details
Enum HandleMock # 
Instance details

Defined in System.FS.Sim.MockFS

Generic HandleMock # 
Instance details

Defined in System.FS.Sim.MockFS

Associated Types

type Rep HandleMock :: Type -> Type #

Show HandleMock # 
Instance details

Defined in System.FS.Sim.MockFS

Eq HandleMock # 
Instance details

Defined in System.FS.Sim.MockFS

Ord HandleMock # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep HandleMock # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep HandleMock = D1 ('MetaData "HandleMock" "System.FS.Sim.MockFS" "fs-sim-0.3.1.0-c0737daea019b4a86c2a751c72ae5b30966c50b66597c67533589e92aee29ad8" 'True) (C1 ('MetaCons "HandleMock" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

data MockFS #

Instances

Instances details
Generic MockFS # 
Instance details

Defined in System.FS.Sim.MockFS

Associated Types

type Rep MockFS :: Type -> Type #

Methods

from :: MockFS -> Rep MockFS x #

to :: Rep MockFS x -> MockFS #

Show MockFS # 
Instance details

Defined in System.FS.Sim.MockFS

Monad m => MonadState MockFS (FSSimT m) # 
Instance details

Defined in System.FS.Sim.Prim

Methods

get :: FSSimT m MockFS #

put :: MockFS -> FSSimT m () #

state :: (MockFS -> (a, MockFS)) -> FSSimT m a #

type Rep MockFS # 
Instance details

Defined in System.FS.Sim.MockFS

type Rep MockFS = D1 ('MetaData "MockFS" "System.FS.Sim.MockFS" "fs-sim-0.3.1.0-c0737daea019b4a86c2a751c72ae5b30966c50b66597c67533589e92aee29ad8" 'False) (C1 ('MetaCons "MockFS" 'PrefixI 'True) (S1 ('MetaSel ('Just "mockFiles") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Files) :*: (S1 ('MetaSel ('Just "mockHandles") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Map HandleMock HandleState)) :*: S1 ('MetaSel ('Just "mockNextHandle") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 HandleMock))))

HasBufFS

hGetBufSome :: (CanSimFS m, PrimMonad m) => Handle' -> MutableByteArray (PrimState m) -> BufferOffset -> ByteCount -> m ByteCount #

hGetBufSomeAt :: (CanSimFS m, PrimMonad m) => Handle' -> MutableByteArray (PrimState m) -> BufferOffset -> ByteCount -> AbsOffset -> m ByteCount #

hPutBufSome :: (CanSimFS m, PrimMonad m) => Handle' -> MutableByteArray (PrimState m) -> BufferOffset -> ByteCount -> m ByteCount #

hPutBufSomeAt :: (CanSimFS m, PrimMonad m) => Handle' -> MutableByteArray (PrimState m) -> BufferOffset -> ByteCount -> AbsOffset -> m ByteCount #