Source file reverse_path.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
type t = Path.t option
let equal a b = match a, b with
| Some a, Some b -> Path.equal a b
| None, None -> true
| _, _ -> false
let pp = Fmt.option Path.pp
module Decoder = struct
open Angstrom
let reverse_path = (Path.Decoder.path >>| fun t -> Some t) <|> (string "<>" *> return None)
let esmtp_keyword =
satisfy Domain.Decoder.(is_alpha or is_digit)
>>= fun pre -> take_while Domain.Decoder.(is_alpha or is_digit or is_dash)
>>| fun lst -> String.concat "" [ String.make 1 pre ; lst ]
let esmtp_value = take_while1 (function '\033' .. '\060' | '\062' .. '\126' -> true | _ -> false)
let esmtp_param =
esmtp_keyword
>>= fun key -> (option None (char '=' *> esmtp_value >>| fun x -> Some x))
>>| fun value -> (key, value)
let mail_parameters = esmtp_param >>= fun x -> many (char ' ' *> esmtp_param) >>| fun r -> x :: r
let of_string x =
let p =
reverse_path
>>= fun reverse_path -> option [] (char ' ' *> mail_parameters)
>>| fun parameters -> (reverse_path, parameters) in
match parse_string p x with
| Ok v -> v
| Error _ -> Fmt.invalid_arg "Invalid reverse-path: %s" x
end
module Encoder = struct
let to_string = function
| None -> "<>"
| Some path -> Path.Encoder.to_string path
end