package streamable

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file keyed_container_clause.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
open! Base
open! Import
include Keyed_container_clause_intf

module Make (X : X) = struct
  let assert_arity_is_expected ~longident_loc ~actual_arity ~expected_arity =
    if actual_arity <> expected_arity
    then
      Location.raise_errorf
        ~loc:longident_loc.loc
        "The arity of `%s' was expected to be %d but was found to be %d"
        (Longident.name longident_loc.txt)
        expected_arity
        actual_arity
  ;;

  let match_on_submodule_form ~core_type =
    match core_type.ptyp_desc with
    | Ptyp_constr (longident_loc, type_parameters) ->
      (match Helpers.if_module_dot_t_then_module core_type with
       | None -> None
       | Some module_longident_loc ->
         (match Helpers.split_longident module_longident_loc.txt with
          | `prefix (Some prefix), `last last when String.(last = X.Submodule_form.name)
            ->
            assert_arity_is_expected
              ~longident_loc
              ~actual_arity:(List.length type_parameters)
              ~expected_arity:X.Submodule_form.arity;
            Some (prefix, X.Submodule_form.value_types ~type_parameters)
          | _ -> None))
    | _ -> None
  ;;

  let match_on_parameterized_form ~core_type =
    match core_type.ptyp_desc with
    | Ptyp_constr (longident_loc, type_parameters) ->
      (match
         Helpers.longident_is_like_t
           longident_loc.txt
           ~primitive_name:None
           ~first_module_name:X.Parameterized_form.name
       with
       | false -> None
       | true  ->
         assert_arity_is_expected
           ~longident_loc
           ~actual_arity:(List.length type_parameters)
           ~expected_arity:X.Parameterized_form.arity;
         let%bind atomic_type = X.Parameterized_form.key_type ~type_parameters in
         let children_types = X.Parameterized_form.value_types ~type_parameters in
         let atomic_longident =
           match Helpers.if_module_dot_t_then_module atomic_type with
           | Some longident_loc -> longident_loc.txt
           | None -> lident (String.capitalize (string_of_core_type atomic_type))
         in
         Some (atomic_longident, children_types))
    | _ -> None
  ;;

  let maybe_match type_ (_ : Ctx.t) =
    let%bind core_type = Type.match_core_type type_ in
    let%map atomic_longident, children_types =
      Option.first_some
        (match_on_submodule_form     ~core_type)
        (match_on_parameterized_form ~core_type)
    in
    ({ children      = List.map children_types ~f:Type.core_type
     ; apply_functor =
         (fun ctx children ->
            let loc = ctx.loc in
            Helpers.apply_streamable_dot
              ctx
              ~functor_name:[%string "Of_%{String.lowercase X.Parameterized_form.name}"]
              ~arguments:(pmod_ident ~loc (Loc.make ~loc atomic_longident) :: children))
     }
     : Clause.Match.t)
  ;;
end
OCaml

Innovation. Community. Security.