123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687typet=stringletcompareab=leta=String.lowercase_asciiainletb=String.lowercase_asciibinString.compareabletequalab=compareab=0letcapitalizex=letcapitalizeresidx=letmap=function'a'..'z'aschr->Char.unsafe_chr(Char.codechr-32)|chr->chrinBytes.setresidx(map(Bytes.getresidx))inletis_dash_or_space=function' '|'-'->true|_->falseinletres=Bytes.of_stringxinfori=0toString.lengthx-1doifi>0&&is_dash_or_spacex.[i-1]thencapitalizeresielseifi=0thencapitalizeresidone;Bytes.unsafe_to_stringresletcanonicalize=String.lowercase_asciiexceptionBreakletis_ftext=function|'\033'..'\057'|'\059'..'\126'->true|_->false(* XXX(dinosaure): from [Rfc5322] but to avoid cyclic dependency. *)letof_stringx=tryfori=0toString.lengthx-1doifnot(is_ftextx.[i])thenraiseBreakdone;OkxwithBreak->Rresult.R.error_msgf"Invalid field: %S"xletof_string_exnx=matchof_stringxwith|Okx->x|Error(`Msgerr)->Fmt.invalid_arg"%s"errletv=of_string_exnletpp=Fmt.usingcapitalizeFmt.stringletprefixed_byprefixfield=ifString.containsprefix'-'thenFmt.invalid_arg"Field.prefixed_by: %s contains '-'"prefix;matchString.(split_on_char'-'(lowercase_asciifield))with|[]->assertfalse(* XXX(dinosaure): see invariants of [split_on_char]. *)|[x]->false|x::r->String.(equalx(lowercase_asciiprefix))moduleEncoder=structopenEncoderletfield_name=usingcapitalizestringendletdate=v"Date"letfrom=v"From"letsender=v"Sender"letreply_to=v"Reply-To"letcc=v"Cc"letbcc=v"Bcc"letsubject=v"Subject"letmessage_id=v"Message-ID"letin_reply_to=v"In-Reply-To"letreferences=v"References"letcomments=v"Comments"letkeywords=v"Keywords"letreceived=v"Received"letreturn_path=v"Return-Path"letcontent_type=v"Content-Type"letcontent_encoding=v"Content-Transfer-Encoding"letmime_version=v"MIME-Version"letcontent_id=v"Content-ID"letcontent_description=v"Content-Description"letresent_date=v"Resent-Date"letresent_from=v"Resent-From"letresent_sender=v"Resent-Sender"letresent_to=v"Resent-To"letresent_cc=v"Resent-Cc"letresent_bcc=v"Resent-Bcc"letresent_message_id=v"Resent-Message-ID"letresent_reply_to=v"Resent-Reply-To"