(A:
sig
type t
type character
val get : t -> int -> character
val length: t -> int
val sub_exn: t -> index:int -> length:int -> t
end) = struct
let rec sub_same_tl t ~comp ~len ~off =
let rec loop i =
i = len || (A.get t (off + i) = A.get comp i) && loop (i + 1)
in
(A.length t >= len) && loop 0
let is_prefix t ~prefix =
let len = A.length prefix in
sub_same_tl t ~comp:prefix ~len ~off:0
let is_suffix t ~suffix =
let len = A.length suffix and lt = A.length t in
sub_same_tl t ~comp:suffix ~len ~off:(lt - len)
let chop_prefix_exn t ~prefix =
let len = A.length prefix and lt = A.length t in
if sub_same_tl t ~comp:prefix ~len ~off:0
then A.sub_exn t ~index:len ~length:(lt - len)
else raise (Invalid_argument "not a prefix")
let chop_prefix t ~prefix =
try Some (chop_prefix_exn t prefix)
with _ -> None
let chop_suffix_exn t ~suffix =
let len = A.length suffix and lt = A.length t in
if sub_same_tl t ~comp:suffix ~len ~off:(lt - len)
then A.sub_exn t ~index:0 ~length:(lt - len)
else raise (Invalid_argument "not a suffix")
let chop_suffix t ~suffix =
try Some (chop_suffix_exn t suffix)
with _ -> None
end