F #, FParsec e chamando um analisador de fluxo recursivamente

Estou desenvolvendo um analisador MIME de várias partes usando F # e FParsec. Estou desenvolvendo iterativamente e, portanto, esse código é altamente não refinado e quebradiço - apenas resolve meu primeiro problema imediato. Vermelho, Verde, Refatorador.

Eu sou obrigado a analisar um fluxo em vez de uma string, o que realmente está me dando um loop. Dada essa restrição, na melhor das hipóteses, preciso chamar um analisador recursivamente. Como fazer isso está além do meu conhecimento, pelo menos da maneira que procedi até agora.

namespace MultipartMIMEParser

open FParsec
open System.IO

type private Post = { contentType : string
                    ; boundary    : string
                    ; subtype     : string
                    ; content     : string }

type MParser (s:Stream) =
  let ($) f x = f x
  let ascii = System.Text.Encoding.ASCII
  let str cs = System.String.Concat (cs:char list)
  let q = "\""
  let qP = pstring q
  let pSemicolon = pstring ";"
  let manyNoDoubleQuote = many $ noneOf q
  let enquoted = between qP qP manyNoDoubleQuote |>> str
  let skip = skipStringCI
  let pContentType = skip "content-type: "
                     >>. manyTill anyChar (attempt $ preturn () .>> pSemicolon)
                     |>> str
  let pBoundary = skip " boundary=" >>. enquoted
  let pSubtype = opt $ pSemicolon >>. skip " type=" >>. enquoted
  let pContent = many anyChar |>> str // TODO: The content parser needs to recurse on the stream.
  let pStream = pipe4 pContentType pBoundary pSubtype pContent
                      $ fun c b t s -> { contentType=c; boundary=b; subtype=t; content=s }
  let result s = match runParserOnStream pStream () "" s ascii with
                 | Success (r,_,_) -> r
                 | Failure (e,_,_) -> failwith (sprintf "%A" e)
  let r = result s
  member p.ContentType = r.contentType
  member p.Boundary = r.boundary
  member p.ContentSubtype = r.subtype
  member p.Content = r.content

A primeira linha do exemplo POST segue:

content-type: Multipart/related; boundary="RN-Http-Body-Boundary"; type="multipart/related"

Ele abrange uma única linha no arquivo. Sub-partes adicionais no conteúdo incluemcontent-type valores que abrangem várias linhas, por isso sei que precisarei refinar meus analisadores para poder reutilizá-los.

De alguma forma eu tenho que ligarpContent com os resultados (string?) depBoundary para que eu possa dividir o restante do fluxo nos limites apropriados e, de alguma forma, retornar várias partes para o conteúdo da postagem, cada uma das quais será uma postagem separada, com cabeçalhos e conteúdo (que obviamente terá que ser outra coisa) que uma string). Minha cabeça está girando. Esse código já parece complexo demais para analisar uma única linha.

Muita apreciação pela perspicácia e sabedoria!

questionAnswers(1)

yourAnswerToTheQuestion