(** Demonstration of enhanced header processing functionality This example shows how to use the new structured header parsing capabilities that implement RFC 8621 Section 4.1.2 access patterns. *) open Jmap_email let demo_header_parsing () = Printf.printf "=== JMAP Header Processing Demo ===\n\n"; (* Create some example headers *) let from_header = Header.create_unsafe ~name:"From" ~value:"\"John Smith\" , jane@example.com" () in let subject_header = Header.create_unsafe ~name:"Subject" ~value:" =?UTF-8?Q?Test_Subject_with_=C3=A9ncoding?= " () in let message_id_header = Header.create_unsafe ~name:"Message-ID" ~value:"" () in let date_header = Header.create_unsafe ~name:"Date" ~value:"2024-01-15T10:30:00Z" () in let list_post_header = Header.create_unsafe ~name:"List-Post" ~value:", " () in (* Demonstrate Raw access pattern *) Printf.printf "1. Raw Access Pattern:\n"; Printf.printf " From (raw): %s\n" (Header.as_raw from_header); Printf.printf " Subject (raw): %s\n\n" (Header.as_raw subject_header); (* Demonstrate Text access pattern *) Printf.printf "2. Text Access Pattern (with RFC 2047 decoding):\n"; (match Header.as_text subject_header with | Ok text -> Printf.printf " Subject (decoded): %s\n" text | Error _ -> Printf.printf " Subject: Parse error\n"); Printf.printf "\n"; (* Demonstrate Addresses access pattern *) Printf.printf "3. Addresses Access Pattern:\n"; (match Header.as_addresses from_header with | Ok addresses -> Printf.printf " From addresses (%d found):\n" (List.length addresses); List.iteri (fun i addr -> match Address.name addr with | Some name -> Printf.printf " %d. %s <%s>\n" (i+1) name (Address.email addr) | None -> Printf.printf " %d. <%s>\n" (i+1) (Address.email addr) ) addresses | Error _ -> Printf.printf " From: Parse error\n"); Printf.printf "\n"; (* Demonstrate MessageIds access pattern *) Printf.printf "4. MessageIds Access Pattern:\n"; (match Header.as_message_ids message_id_header with | Ok ids -> Printf.printf " Message-ID: [%s]\n" (String.concat "; " ids) | Error _ -> Printf.printf " Message-ID: Parse error\n"); Printf.printf "\n"; (* Demonstrate Date access pattern *) Printf.printf "5. Date Access Pattern:\n"; (match Header.as_date date_header with | Ok date -> Printf.printf " Date: %f (timestamp)\n" (Jmap.Date.to_timestamp date) | Error _ -> Printf.printf " Date: Parse error\n"); Printf.printf "\n"; (* Demonstrate URLs access pattern *) Printf.printf "6. URLs Access Pattern:\n"; (match Header.as_urls list_post_header with | Ok urls -> Printf.printf " List-Post URLs: [%s]\n" (String.concat "; " urls) | Error _ -> Printf.printf " List-Post: Parse error\n"); Printf.printf "\n"; (* Demonstrate utility functions *) Printf.printf "7. Header List Utilities:\n"; let headers = [from_header; subject_header; message_id_header] in (match Header.find_and_parse_as_text headers "Subject" with | Some text -> Printf.printf " Found Subject: %s\n" text | None -> Printf.printf " Subject not found or not parseable\n"); (match Header.find_and_parse_as_addresses headers "From" with | Some addrs -> Printf.printf " Found %d From addresses\n" (List.length addrs) | None -> Printf.printf " From not found or not parseable\n"); Printf.printf "\n=== Demo Complete ===\n" let () = demo_header_parsing ()