I'm trying to write a Conduit
using an attoparsec parser. Specifically, given parseOne :: Parser T
, I'd like to construct a Conduit ByteString m T
that repeatedly applies the parser to the input and streams the results.
attoparsec-conduit offers sinkParser
to turn a Parser
into a Sink
, but how can I turn this Sink
into a Conduit
? What I'm looking for is a function like:
conduitSink :: (Resource m) => Sink a m b -> Conduit a m b
which repeatedly feeds data into the Sink
, producing each result as it goes. It seems like it could be written fairly easily as a manual loop, but I'm wondering if there's a better way.
The lack of this seemingly-obvious function in the conduit library makes me think I might be doing something wrong; is there a better way to accomplish this? The use case is turning raw bytes into the parsed form of a message-based network protocol, to be processed by later stages of the pipeline. I already have the opposite direction (i.e. Conduit T m ByteString
) thanks to blaze-builder-conduit, so this seemed like the most natural way to structure things.
conduitParser :: (AttoparsecInput a, ResourceThrow m) => Parser a b -> Conduit a m b
to its interface using this technique, or is it a simple omission? – Inkstand