let decoder (fields : [> field ] list) =
{ Parser.f = fun i s fail succ ->
let rec catch garbage acc lst = match lst, acc with
| `ResentDate date :: r, ([] as r')
| `ResentDate date :: r, (({ date = Some _; _ } :: _) as r') ->
catch garbage ({ default with date = Some date } :: r') r
| `ResentDate date :: r, x :: r' ->
catch garbage ({ x with date = Some date } :: r') r
| `ResentFrom from :: r, ([] as r')
| `ResentFrom from :: r, (({ from = _ :: _; _ } :: _) as r') ->
catch garbage ({ default with from = from } :: r') r
| `ResentFrom from :: r, x :: r' ->
catch garbage ({ x with from = x.from @ from } :: r') r
| `ResentSender v :: r, x :: r' ->
catch garbage ({ x with sender = Some v } :: r') r
| `ResentTo v :: r, x :: r' ->
catch garbage ({ x with to' = x.to' @ v } :: r') r
| `ResentCc v :: r, x :: r' ->
catch garbage ({ x with cc = x.cc @ v } :: r') r
| `ResentBcc v :: r, x :: r' ->
catch garbage ({ x with bcc = x.bcc @ v } :: r') r
| `ResentMessageID v :: r, x :: r' ->
catch garbage ({ x with msg_id = Some v } :: r') r
| `ResentReplyTo v :: r, x :: r' ->
catch garbage ({ x with reply_to = x.reply_to @ v } :: r') r
| field :: r, acc ->
catch (field :: garbage) acc r
| [], acc -> acc, List.rev garbage
in
succ i s (catch [] [] fields) }