Source file selector.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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
module Stable = struct
  open Core.Core_stable

  module Base = struct
    module V1 = struct
      type t =
        [ `exists_header of string * Re2.Stable.V1_no_options.t
        | `all_headers of string * Re2.Stable.V1_no_options.t
        ]
      [@@deriving bin_shape, sexp]

      let%expect_test _ =
        print_endline [%bin_digest: t];
        [%expect {| cbce30b485bdbeb9e93285287a91e7f5 |}]
      ;;
    end
  end

  module V1 = struct
    type t = Base.V1.t Blang.V1.t [@@deriving bin_shape, sexp]

    let%expect_test _ =
      print_endline [%bin_digest: t];
      [%expect {| 96b50dce93691f115ea076e70421edf9 |}]
    ;;
  end
end

open Core
open! Import
module Regex = Re2

module Base = struct
  type t =
    (* When adding to this type, don't forget to add to examples below. *)
    [ `exists_header of string * Regex.t
    | `all_headers of string * Regex.t
    ]
  [@@deriving sexp_of]

  let matches' t headers =
    match t with
    | `exists_header (header, regex) ->
      let headers = Headers.find_all headers header in
      List.exists headers ~f:(Regex.matches regex)
    | `all_headers (header, regex) ->
      let headers = Headers.find_all headers header in
      List.for_all headers ~f:(Regex.matches regex)
  ;;

  let matches t email = matches' t (Email.headers email)

  let examples =
    [ `exists_header ("cc", Regex.of_string ".*@janestreet.com")
    ; `all_headers ("cc", Regex.of_string ".*@janestreet.com")
    ]
  ;;
end

type t = Base.t Blang.t [@@deriving sexp_of]

let matches' t headers = Blang.eval t (fun base -> Base.matches' base headers)
let matches t email = matches' t (Email.headers email)
let example : t = Blang.and_ (List.map Base.examples ~f:Blang.base)