OCaml HTML5 parser/serialiser based on Python's JustHTML
1(** Validation messages with typed error codes. *)
2
3type severity = Error | Warning | Info
4
5type location = {
6 line : int;
7 column : int;
8 end_line : int option;
9 end_column : int option;
10 system_id : string option;
11}
12
13type t = {
14 severity : severity;
15 message : string;
16 code : string;
17 error_code : Error_code.t option;
18 location : location option;
19 element : string option;
20 attribute : string option;
21 extract : string option;
22}
23
24let make_location ~line ~column ?end_line ?end_column ?system_id () =
25 { line; column; end_line; end_column; system_id }
26
27(** Create a message from a typed error code *)
28let of_error_code ?location ?element ?attribute ?extract error_code =
29 let severity = match Error_code.severity error_code with
30 | Error_code.Error -> Error
31 | Error_code.Warning -> Warning
32 | Error_code.Info -> Info
33 in
34 {
35 severity;
36 message = Error_code.to_message error_code;
37 code = Error_code.code_string error_code;
38 error_code = Some error_code;
39 location;
40 element;
41 attribute;
42 extract;
43 }
44
45(** Create a message with manual message text (for backwards compatibility during migration) *)
46let make ~severity ~message ?(code="generic") ?location ?element ?attribute ?extract () =
47 { severity; message; code; error_code = None; location; element; attribute; extract }
48
49let error ~message ?(code="generic") ?location ?element ?attribute ?extract () =
50 make ~severity:Error ~message ~code ?location ?element ?attribute ?extract ()
51
52let warning ~message ?(code="generic") ?location ?element ?attribute ?extract () =
53 make ~severity:Warning ~message ~code ?location ?element ?attribute ?extract ()
54
55let info ~message ?(code="generic") ?location ?element ?attribute ?extract () =
56 make ~severity:Info ~message ~code ?location ?element ?attribute ?extract ()
57
58let severity_to_string = function
59 | Error -> "error"
60 | Warning -> "warning"
61 | Info -> "info"
62
63let pp_severity fmt severity =
64 Format.pp_print_string fmt (severity_to_string severity)
65
66let pp_location fmt loc =
67 (match loc.system_id with
68 | Some sid -> Format.fprintf fmt "%s:" sid
69 | None -> ());
70 Format.fprintf fmt "%d:%d" loc.line loc.column;
71 match (loc.end_line, loc.end_column) with
72 | Some el, Some ec when el = loc.line && ec > loc.column ->
73 Format.fprintf fmt "-%d" ec
74 | Some el, Some ec when el > loc.line ->
75 Format.fprintf fmt "-%d:%d" el ec
76 | _ -> ()
77
78let pp fmt msg =
79 (match msg.location with
80 | Some loc ->
81 pp_location fmt loc;
82 Format.fprintf fmt ": "
83 | None -> ());
84 pp_severity fmt msg.severity;
85 Format.fprintf fmt " [%s]" msg.code;
86 Format.fprintf fmt ": %s" msg.message;
87 (match msg.element with
88 | Some elem -> Format.fprintf fmt " (element: %s)" elem
89 | None -> ());
90 match msg.attribute with
91 | Some attr -> Format.fprintf fmt " (attribute: %s)" attr
92 | None -> ()
93
94let to_string msg =
95 let buf = Buffer.create 256 in
96 let fmt = Format.formatter_of_buffer buf in
97 pp fmt msg;
98 Format.pp_print_flush fmt ();
99 Buffer.contents buf