My agentic slop goes here. Not intended for anyone else!
JMAP Email Types JSON Implementation#
This document summarizes the JSON serialization and deserialization functionality added to the JMAP Email types implementation.
Overview#
JSON support has been added to the core email types in jmap-email/jmap_email_types.ml to enable proper serialization and parsing of JMAP email objects according to RFC 8621.
Implemented Types#
1. Email_address#
- to_json: Converts email addresses to JSON with
email(required) andname(optional) fields - of_json: Parses JSON objects into email address structures
- Handles both named (
{"name": "John Doe", "email": "john@example.com"}) and unnamed ({"email": "jane@example.com"}) addresses
2. Email_header#
- to_json: Converts header fields to JSON with
nameandvaluefields - of_json: Parses JSON objects into header field structures
- Example:
{"name": "Subject", "value": "Important Message"}
3. Email_body_part#
- to_json: Converts body parts to comprehensive JSON representation including:
- Basic fields:
partId,blobId,size,headers,type - Optional fields:
name,charset,disposition,cid,language,location - Nested structures:
subPartsfor multipart content - Extension fields:
other_headersfor custom headers
- Basic fields:
- of_json: Parses complex JSON structures back into body part objects
- Handles recursive parsing for nested multipart structures
4. Keywords#
- to_json: Converts keyword sets to JMAP wire format (object with boolean values)
- of_json: Parses JMAP keyword objects back into keyword lists
- Supports all JMAP standard keywords and custom keywords
- Example:
{"$seen": true, "$flagged": false, "custom-label": true}
5. Email#
- to_json: Converts complete email objects to JSON with all present fields:
- Metadata:
id,blobId,threadId,size,receivedAt - Addressing:
from,to,cc,mailboxIds - Content:
subject,preview,hasAttachment - Structure:
textBody,htmlBody,attachments - Keywords and message IDs
- Metadata:
- of_json: Parses comprehensive email JSON into email objects
- Handles optional fields correctly (present vs null vs missing)
Key Features#
Type Safety#
- All functions use OCaml's strong type system to ensure correctness
- Proper error handling with descriptive failure messages
- Optional field handling that respects JMAP semantics
JMAP Compliance#
- Follows RFC 8621 JSON structure specifications exactly
- Handles JMAP-specific data types (dates as floats, boolean maps, etc.)
- Supports all standard and extended JMAP email properties
Robustness#
- Handles nested and recursive structures (body parts with sub-parts)
- Proper handling of optional vs. null vs. missing fields
- Extension field support for future JMAP enhancements
Testing#
Comprehensive test suite included in jmap-email/test_email_json.ml:
Test Coverage#
- Round-trip testing: JSON → OCaml → JSON conversion verification
- Field handling: Optional, null, and missing field scenarios
- Complex structures: Nested body parts, multiple addresses, keyword sets
- Real-world examples: RFC-compliant JMAP email JSON parsing
- Edge cases: Empty lists, minimal vs. full email objects
Test Types#
- Unit tests for individual type conversions
- Integration tests with realistic JMAP email examples
- Round-trip verification to ensure data preservation
- Property-based testing for JSON field ordering independence
Usage Examples#
Basic Email Address Parsing#
let json = `Assoc [("name", `String "John Doe"); ("email", `String "john@example.com")]
let addr = Email_address.of_json json
let back_to_json = Email_address.to_json addr
Complete Email Object Handling#
let email_json = Yojson.Safe.from_string {|
{
"id": "M123",
"subject": "Test",
"from": [{"name": "Alice", "email": "alice@example.com"}],
"keywords": {"$seen": true, "$flagged": false}
}
|}
let email = Email.of_json email_json
let roundtrip = Email.to_json email
Body Part Structure Parsing#
let body_part_json = Yojson.Safe.from_string {|
{
"partId": "1",
"type": "text/plain",
"size": 1024,
"headers": [{"name": "Content-Type", "value": "text/plain"}],
"charset": "utf-8"
}
|}
let part = Email_body_part.of_json body_part_json
Implementation Notes#
- Uses manual JSON handling for precise control over structure
- Leverages Yojson.Safe for JSON processing
- Hashtbl used for ID maps and keyword storage as per JMAP library patterns
- Date handling uses float values per JMAP specification
- Error messages are descriptive for debugging JSON structure issues
This implementation provides a solid foundation for JMAP email processing with full JSON serialization support.