Parsec doesn't by default backtrack so many anyChar
will just slurp the rest of your text. Instead consider something like
manyTill line $ try (string "From: ")
b <- manyTill anyChar newline
many line
eof
return b
Note that since we want to backtrack if our end
parser fails with manyTill
, it's important to make sure that it backtracks properly, thus we use try
.
Now this still fails because your email doesn't end in a newline, so line
starts to succeed, then fails, causing the whole parser to fail rather than backtracking. If you can't change this than change it to
many (try line)
To clarify, parsec considers a parser to have failed if it fails without consuming any input by default. If it consumes even one character and then fails, your whole parser dies. If you want backtracking behaviour so this doesn't happen, use try
.
For extracting the body,
getBody = do
manyTill anyChar (try $ string "boundary=")
boundary <- manyTill anyChar newline
manyTill anyChar (try $ string boundary) -- Get to the boundary
manyTill anyChar (try $ string boundary) -- Read the body