Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
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
- empty :: MockFS
- example :: MockFS
- handleIsOpen :: MockFS -> HandleMock -> Bool
- numOpenHandles :: MockFS -> Int
- openHandles :: MockFS -> [OpenHandleState]
- pretty :: MockFS -> String
- dumpState :: CanSimFS m => m String
- hClose :: CanSimFS m => Handle' -> m ()
- hGetSize :: CanSimFS m => Handle' -> m Word64
- hGetSome :: CanSimFS m => Handle' -> Word64 -> m ByteString
- hGetSomeAt :: CanSimFS m => Handle' -> Word64 -> AbsOffset -> m ByteString
- hIsOpen :: CanSimFS m => Handle' -> m Bool
- hOpen :: CanSimFS m => FsPath -> OpenMode -> m Handle'
- hPutSome :: CanSimFS m => Handle' -> ByteString -> m Word64
- hSeek :: CanSimFS m => Handle' -> SeekMode -> Int64 -> m ()
- hTruncate :: CanSimFS m => Handle' -> Word64 -> m ()
- createDirectory :: CanSimFS m => FsPath -> m ()
- createDirectoryIfMissing :: CanSimFS m => Bool -> FsPath -> m ()
- doesDirectoryExist :: CanSimFS m => FsPath -> m Bool
- doesFileExist :: CanSimFS m => FsPath -> m Bool
- listDirectory :: CanSimFS m => FsPath -> m (Set String)
- removeDirectoryRecursive :: CanSimFS m => FsPath -> m ()
- removeFile :: CanSimFS m => FsPath -> m ()
- renameFile :: CanSimFS m => FsPath -> FsPath -> m ()
- type Files = FsTree ByteString
- mockFiles :: MockFS -> Files
- data ClosedHandleState
- data FilePtr
- data HandleState
- data OpenHandleState
- data HandleMock
- data MockFS
- fromBuffer :: PrimMonad m => MutableByteArray (PrimState m) -> BufferOffset -> ByteCount -> m (Maybe ByteString)
- intoBuffer :: PrimMonad m => MutableByteArray (PrimState m) -> BufferOffset -> ByteString -> m Bool
- 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
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
openHandles :: MockFS -> [OpenHandleState] #
Debugging
Operations on files
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.
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
Generic ClosedHandleState # | |
Defined in System.FS.Sim.MockFS Associated Types type Rep ClosedHandleState :: Type -> Type # Methods from :: ClosedHandleState -> Rep ClosedHandleState x # to :: Rep ClosedHandleState x -> ClosedHandleState # | |
Show ClosedHandleState # | |
Defined in System.FS.Sim.MockFS Methods showsPrec :: Int -> ClosedHandleState -> ShowS # show :: ClosedHandleState -> String # showList :: [ClosedHandleState] -> ShowS # | |
type Rep ClosedHandleState # | |
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))) |
File pointer
This is purely an internal abstraction.
Instances
Generic FilePtr # | |
Show FilePtr # | |
type Rep FilePtr # | |
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
Generic HandleState # | |
Defined in System.FS.Sim.MockFS Associated Types type Rep HandleState :: Type -> Type # | |
Show HandleState # | |
Defined in System.FS.Sim.MockFS Methods showsPrec :: Int -> HandleState -> ShowS # show :: HandleState -> String # showList :: [HandleState] -> ShowS # | |
type Rep HandleState # | |
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
Generic OpenHandleState # | |
Defined in System.FS.Sim.MockFS Associated Types type Rep OpenHandleState :: Type -> Type # Methods from :: OpenHandleState -> Rep OpenHandleState x # to :: Rep OpenHandleState x -> OpenHandleState # | |
Show OpenHandleState # | |
Defined in System.FS.Sim.MockFS Methods showsPrec :: Int -> OpenHandleState -> ShowS # show :: OpenHandleState -> String # showList :: [OpenHandleState] -> ShowS # | |
type Rep OpenHandleState # | |
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
Generic MockFS # | |
Show MockFS # | |
Monad m => MonadState MockFS (FSSimT m) # | |
type Rep MockFS # | |
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
fromBuffer :: PrimMonad m => MutableByteArray (PrimState m) -> BufferOffset -> ByteCount -> m (Maybe ByteString) #
intoBuffer :: PrimMonad m => MutableByteArray (PrimState m) -> BufferOffset -> ByteString -> m Bool #
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 #