Safe Haskell | None |
---|---|
Language | Haskell2010 |
A streaming parser for the NAR format
Synopsis
- newtype NarParser m a = NarParser {
- runNarParser :: StateT ParserState (ExceptT String (ReaderT (NarEffects m) m)) a
- runParser :: forall m a. (MonadIO m, MonadBaseControl IO m) => NarEffects m -> NarParser m a -> Handle -> FilePath -> m (Either String a)
- data ParserState = ParserState {
- tokenStack :: ![Text]
- directoryStack :: ![String]
- handle :: Handle
- links :: [LinkInfo]
- parseNar :: (MonadIO m, MonadFail m) => NarParser m ()
- parseFSO :: (MonadIO m, MonadFail m) => NarParser m ()
- parseSymlink :: (MonadIO m, MonadFail m) => NarParser m ()
- data LinkInfo = LinkInfo {}
- parseFile :: forall m. (MonadIO m, MonadFail m) => NarParser m ()
- parseDirectory :: (MonadIO m, MonadFail m) => NarParser m ()
- parseStr :: (MonadIO m, MonadFail m) => NarParser m Text
- parseLength :: (MonadIO m, MonadFail m) => NarParser m Int64
- expectStr :: (MonadIO m, MonadFail m) => Text -> NarParser m ()
- expectRawString :: (MonadIO m, MonadFail m) => ByteString -> NarParser m ()
- matchStr :: (MonadIO m, MonadFail m) => [(Text, NarParser m a)] -> NarParser m a
- parens :: (MonadIO m, MonadFail m) => NarParser m a -> NarParser m a
- createLinks :: MonadIO m => NarParser m ()
- consume :: (MonadIO m, MonadFail m) => Int -> NarParser m ByteString
- popStr :: Monad m => NarParser m (Maybe Text)
- pushStr :: Monad m => Text -> NarParser m ()
- pushFileName :: Monad m => FilePath -> NarParser m ()
- popFileName :: Monad m => NarParser m ()
- currentFile :: Monad m => NarParser m FilePath
- pushLink :: Monad m => LinkInfo -> NarParser m ()
- testParser :: m ~ IO => NarParser m a -> ByteString -> m (Either String a)
- testParser' :: m ~ IO => FilePath -> IO (Either String ())
- padLen :: Int -> Int
- dbgState :: MonadIO m => NarParser m ()
Documentation
newtype NarParser m a Source #
NarParser is a monad for parsing a Nar file as a byte stream
and reconstructing the file system objects inside
See the definitions of NarEffects
for a description
of the actions the parser can take, and ParserState
for the
internals of the parser
NarParser | |
|
Instances
:: forall m a. (MonadIO m, MonadBaseControl IO m) | |
=> NarEffects m | Provide the effects set, usually |
-> NarParser m a | A parser to run, such as |
-> Handle | A handle the stream containg the NAR. It should already be
open and in |
-> FilePath | The root file system object to be created by the NAR |
-> m (Either String a) |
Run a NarParser
over a byte stream
This is suitable for testing the top-level NAR parser, or any of the
smaller utilities parsers, if you have bytes appropriate for them
data ParserState Source #
ParserState | |
|
Instances
Monad m => MonadState ParserState (NarParser m) Source # | |
Defined in System.Nix.Internal.Nar.Parser get :: NarParser m ParserState # put :: ParserState -> NarParser m () # state :: (ParserState -> (a, ParserState)) -> NarParser m a # |
Parsers for NAR components
parseNar :: (MonadIO m, MonadFail m) => NarParser m () Source #
Parse a NAR byte string, producing ()
.
Parsing a NAR is mostly used for its side-effect: producing
the file system objects packed in the NAR. That's why we pure ()
parseSymlink :: (MonadIO m, MonadFail m) => NarParser m () Source #
Parse a symlink from a NAR, storing the link details in the parser state
We remember links rather than immediately creating file system objects
from them, because we might encounter a link in the NAR before we
encountered its target, and in this case, creating the link will fail
The final step of creating links is handle by createLinks
Internal data type representing symlinks encountered in the NAR
parseFile :: forall m. (MonadIO m, MonadFail m) => NarParser m () Source #
When the NAR includes a file, we read from the NAR handle in chunks and write the target in chunks. This lets us avoid reading the full contents of the encoded file into memory
parseDirectory :: (MonadIO m, MonadFail m) => NarParser m () Source #
Parse a NAR encoded directory, being careful not to hold onto file handles for target files longer than needed
Utility parsers
parseStr :: (MonadIO m, MonadFail m) => NarParser m Text Source #
Short strings guiding the NAR parsing are prefixed with their
length, then encoded in ASCII, and padded to 8 bytes. parseStr
captures this logic
parseLength :: (MonadIO m, MonadFail m) => NarParser m Int64 Source #
Get an Int64 describing the length of the upcoming string, according to NAR's encoding of ints
expectStr :: (MonadIO m, MonadFail m) => Text -> NarParser m () Source #
Consume a NAR string and assert that it matches an expectation
expectRawString :: (MonadIO m, MonadFail m) => ByteString -> NarParser m () Source #
Consume a raw string and assert that it equals some expectation. This is usually used when consuming padding 0's
:: (MonadIO m, MonadFail m) | |
=> [(Text, NarParser m a)] | List of expected possible strings and the parsers they should run |
-> NarParser m a |
Consume a NAR string, and dispatch to a parser depending on which string matched
parens :: (MonadIO m, MonadFail m) => NarParser m a -> NarParser m a Source #
Wrap any parser in NAR formatted parentheses (a parenthesis is a NAR string, so it needs length encoding and padding)
createLinks :: MonadIO m => NarParser m () Source #
Sort links in the symlink stack according to their connectivity (Targets must be created before the links that target them)
State manipulation
consume :: (MonadIO m, MonadFail m) => Int -> NarParser m ByteString Source #
Pull n bytes from the underlying handle, failing if fewer bytes are available
popFileName :: Monad m => NarParser m () Source #
Go to the parent level in the directory stack
currentFile :: Monad m => NarParser m FilePath Source #
Convert the current directory stack into a filepath by interspersing the path components with "/"
pushLink :: Monad m => LinkInfo -> NarParser m () Source #
Add a link to the collection of encountered symlinks
Utilities
testParser :: m ~ IO => NarParser m a -> ByteString -> m (Either String a) Source #