12345678910111213141516171819202122232425262728293031323334353637383940open!Import0.Int_replace_polymorphic_comparemoduleBytes=Bytes0moduleString=String0(* Construct a byte string of length 256, mapping every input character code to
its corresponding output character.
Benchmarks indicate that this is faster than the lambda (including cost of
this function), even if target/replacement are just 2 characters each.
Return None if the translation map is equivalent to just the identity. *)lettr_create_map~target~replacement=lettr_map=Bytes.create256infori=0to255doBytes.unsafe_settr_mapi(Char.of_int_exni)done;fori=0to(min(String.lengthtarget)(String.lengthreplacement))-1doletindex=Char.to_int(String.unsafe_gettargeti)inBytes.unsafe_settr_mapindex(String.unsafe_getreplacementi)done;letlast_replacement=String.unsafe_getreplacement(String.lengthreplacement-1)infori=min(String.lengthtarget)(String.lengthreplacement)toString.lengthtarget-1doletindex=Char.to_int(String.unsafe_gettargeti)inBytes.unsafe_settr_mapindexlast_replacementdone;letrechave_any_differenttr_mapi=ifi=256thenfalseelseifChar.(<>)(Bytes0.unsafe_gettr_mapi)(Char.of_int_exni)thentrueelsehave_any_differenttr_map(i+1)in(* quick check on the first target character which will 99% be true *)letfirst_target=String.gettarget0inifChar.(<>)(Bytes0.unsafe_gettr_map(Char.to_intfirst_target))first_target||have_any_differenttr_map0thenSome(Bytes0.unsafe_to_string~no_mutation_while_string_reachable:tr_map)elseNone