My agentic slop goes here. Not intended for anyone else!
at main 10 kB view raw
1(** Email header field representation. 2 3 This module provides types and operations for email header fields as defined in 4 RFC 8621 Section 4.1.3. Each header field consists of a field name and its raw, 5 unprocessed value as it appears in the original email message. 6 7 Header fields follow RFC 5322 syntax and provide access to both standard headers 8 (Subject, From, To, etc.) and custom headers that may not be parsed into specific 9 Email object properties. 10 11 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.3> RFC 8621, Section 4.1.3 - Email Header Fields 12*) 13 14(** Email header field type. 15 16 Represents a single email header field as specified in RFC 8621 Section 4.1.3. 17 Each header consists of a field name and its raw, unprocessed value as it 18 appears in the original email message. 19*) 20type t 21 22(** JSON serialization interface *) 23include Jmap_sigs.JSONABLE with type t := t 24 25(** Pretty-printing interface *) 26include Jmap_sigs.PRINTABLE with type t := t 27 28(** Get the header field name. 29 @param t The header field 30 @return The header field name (e.g., "Subject", "X-Custom-Header") *) 31val name : t -> string 32 33(** Get the raw header field value. 34 @param t The header field 35 @return The unprocessed header value as it appears in the message *) 36val value : t -> string 37 38(** Create a new header field. 39 40 Creates a header field with validation of the field name according to RFC 5322. 41 Header names must contain only printable ASCII characters and cannot contain 42 control characters, spaces, or certain special characters. 43 44 @param name The header field name 45 @param value The raw header field value 46 @return Result containing new header field object or validation error *) 47val create : 48 name:string -> 49 value:string -> 50 unit -> (t, string) result 51 52(** Create a new header field without validation. 53 54 For use when header field names are known to be valid or come from 55 trusted sources like server responses. 56 57 @param name The header field name 58 @param value The raw header field value 59 @return New header field object *) 60val create_unsafe : 61 name:string -> 62 value:string -> 63 unit -> t 64 65(** Convert a list of header fields to JSON array. 66 67 Utility function for converting header field lists to JSON arrays 68 as used in Email body parts and other contexts. 69 70 @param headers List of header fields to convert 71 @return JSON array containing header field objects *) 72val list_to_json : t list -> Yojson.Safe.t 73 74(** Parse a list of header fields from JSON array. 75 76 Utility function for parsing JSON arrays of header field objects. 77 Individual parsing errors are collected and reported. 78 79 @param json JSON array containing header field objects 80 @return Result containing parsed header field list or parse errors *) 81val list_of_json : Yojson.Safe.t -> (t list, string) result 82 83(** Find a header field by name (case-insensitive). 84 85 Searches a list of header fields for the first field matching the given 86 name using case-insensitive comparison as specified in RFC 5322. 87 88 @param headers List of header fields to search 89 @param name Header field name to find 90 @return The first matching header field, or None if not found *) 91val find_by_name : t list -> string -> t option 92 93(** Get all header fields with a given name (case-insensitive). 94 95 Returns all header fields matching the given name. This is useful for 96 headers that may appear multiple times like "Received" or "X-*" headers. 97 98 @param headers List of header fields to search 99 @param name Header field name to find 100 @return List of all matching header fields *) 101val find_all_by_name : t list -> string -> t list 102 103(** Validate a header field name according to RFC 5322. 104 105 Checks that a header field name consists only of printable ASCII characters 106 and does not contain control characters, spaces, or the colon character. 107 108 @param name The header field name to validate 109 @return Ok if valid, Error with description if invalid *) 110val validate_name : string -> (unit, string) result 111 112(** Structured header parsing support for JMAP access patterns *) 113module Value : sig 114 (** Header value access patterns as defined in RFC 8621 Section 4.1.2 *) 115 type access_form = 116 | Raw (** Raw octets as they appear in the message *) 117 | Text (** Decoded and unfolded text *) 118 | Addresses (** Parsed email addresses *) 119 | GroupedAddresses (** Parsed addresses preserving group information *) 120 | MessageIds (** Parsed message ID list *) 121 | Date (** Parsed date value *) 122 | URLs (** Parsed URL list *) 123 124 (** Structured header value types *) 125 type parsed_value = 126 | Raw_value of string 127 | Text_value of string 128 | Addresses_value of Address.t list 129 | GroupedAddresses_value of Address.Group.t list 130 | MessageIds_value of string list 131 | Date_value of Jmap.Date.t 132 | URLs_value of string list 133 134 (** Parse error types *) 135 type parse_error = 136 | Invalid_encoding of string (** RFC 2047 encoding error *) 137 | Malformed_header of string (** Malformed header structure *) 138 | Unsupported_form of string * access_form (** Unsupported access form for header *) 139 | Parse_failure of string (** General parse failure *) 140end 141 142(** Header access pattern functions following RFC 8621 Section 4.1.2 *) 143 144(** Get header value as Raw form. 145 146 Returns the raw octets of the header field value as specified in 147 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.1}RFC 8621 Section 4.1.2.1}. 148 This form always succeeds and returns the header value as-is. 149 150 @param t The header field 151 @return Raw header field value *) 152val as_raw : t -> string 153 154(** Get header value as Text form. 155 156 Processes the header value according to 157 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.2}RFC 8621 Section 4.1.2.2} 158 with white space unfolding, RFC 2047 decoding, and normalization. 159 Only valid for specific header fields as defined in the RFC. 160 161 @param t The header field 162 @return Result containing decoded text or parse error *) 163val as_text : t -> (string, Value.parse_error) result 164 165(** Get header value as parsed email addresses. 166 167 Parses the header as an address-list according to 168 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.3}RFC 8621 Section 4.1.2.3}. 169 Only valid for address-type header fields (From, To, Cc, etc.). 170 171 @param t The header field 172 @return Result containing list of email addresses or parse error *) 173val as_addresses : t -> (Address.t list, Value.parse_error) result 174 175(** Get header value as grouped addresses. 176 177 Similar to addresses but preserves group information according to 178 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.4}RFC 8621 Section 4.1.2.4}. 179 Only valid for address-type header fields. 180 181 @param t The header field 182 @return Result containing list of address groups or parse error *) 183val as_grouped_addresses : t -> (Address.Group.t list, Value.parse_error) result 184 185(** Get header value as message ID list. 186 187 Parses the header as message IDs according to 188 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.5}RFC 8621 Section 4.1.2.5}. 189 Only valid for message ID header fields (Message-ID, In-Reply-To, References). 190 191 @param t The header field 192 @return Result containing list of message IDs or parse error *) 193val as_message_ids : t -> (string list, Value.parse_error) result 194 195(** Get header value as parsed date. 196 197 Parses the header as a date-time according to 198 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.6}RFC 8621 Section 4.1.2.6}. 199 Only valid for date header fields (Date, Resent-Date). 200 201 @param t The header field 202 @return Result containing parsed date or parse error *) 203val as_date : t -> (Jmap.Date.t, Value.parse_error) result 204 205(** Get header value as URL list. 206 207 Parses the header as URLs according to 208 {{:https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.7}RFC 8621 Section 4.1.2.7}. 209 Only valid for URL-type header fields (List-Archive, List-Post, etc.). 210 211 @param t The header field 212 @return Result containing list of URLs or parse error *) 213val as_urls : t -> (string list, Value.parse_error) result 214 215(** Parse header in the specified access form. 216 217 Generic function for parsing a header in any supported access pattern. 218 This provides a unified interface for all parsing operations. 219 220 @param t The header field 221 @param form The desired access form 222 @return Result containing parsed value or parse error *) 223val parse_as : t -> Value.access_form -> (Value.parsed_value, Value.parse_error) result 224 225(** Utility functions for working with header lists *) 226 227(** Find header by name and parse as Text form. 228 @param headers List of header fields to search 229 @param name Header field name to find 230 @return Parsed text value if found and valid, None otherwise *) 231val find_and_parse_as_text : t list -> string -> string option 232 233(** Find header by name and parse as addresses. 234 @param headers List of header fields to search 235 @param name Header field name to find 236 @return List of parsed addresses if found and valid, None otherwise *) 237val find_and_parse_as_addresses : t list -> string -> Address.t list option 238 239(** Find header by name and parse as message IDs. 240 @param headers List of header fields to search 241 @param name Header field name to find 242 @return List of parsed message IDs if found and valid, None otherwise *) 243val find_and_parse_as_message_ids : t list -> string -> string list option 244 245(** Find header by name and parse as date. 246 @param headers List of header fields to search 247 @param name Header field name to find 248 @return Parsed date if found and valid, None otherwise *) 249val find_and_parse_as_date : t list -> string -> Jmap.Date.t option