OCaml HTML5 parser/serialiser based on Python's JustHTML
1(** Message collector for accumulating validation messages. *)
2
3type t = {
4 mutable messages : Message.t list;
5 mutable current_location : Message.location option;
6 mutable cached_reversed : Message.t list option; (* Cache for O(1) repeated access *)
7}
8
9let create () = { messages = []; current_location = None; cached_reversed = None }
10
11let set_current_location t location = t.current_location <- location
12let clear_current_location t = t.current_location <- None
13let get_current_location t = t.current_location
14
15let add t msg =
16 t.messages <- msg :: t.messages;
17 t.cached_reversed <- None (* Invalidate cache *)
18
19(** Add a message from a typed conformance error code *)
20let add_typed t ?location ?element ?attribute ?extract error_code =
21 (* Use provided location, or fall back to current_location *)
22 let loc = match location with
23 | Some _ -> location
24 | None -> t.current_location
25 in
26 let msg = Message.of_conformance_error ?location:loc ?element ?attribute ?extract error_code in
27 add t msg
28
29let messages t =
30 match t.cached_reversed with
31 | Some cached -> cached
32 | None ->
33 let reversed = List.rev t.messages in
34 t.cached_reversed <- Some reversed;
35 reversed
36
37let errors t =
38 List.filter (fun msg -> msg.Message.severity = Message.Error) (messages t)
39
40let warnings t =
41 List.filter (fun msg -> msg.Message.severity = Message.Warning) (messages t)
42
43let infos t =
44 List.filter (fun msg -> msg.Message.severity = Message.Info) (messages t)
45
46let has_errors t =
47 List.exists (fun msg -> msg.Message.severity = Message.Error) t.messages
48
49let count t = List.length t.messages
50
51let error_count t =
52 List.fold_left
53 (fun acc msg ->
54 if msg.Message.severity = Message.Error then acc + 1 else acc)
55 0 t.messages
56
57let clear t =
58 t.messages <- [];
59 t.cached_reversed <- None