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