(** Byte range management for partial downloads *) type t = { start : int64; end_ : int64; (* inclusive *) } let create ~start ~end_ = if start < 0L || end_ < start then invalid_arg (Printf.sprintf "Invalid range: %Ld-%Ld" start end_) else { start; end_ } let start r = r.start let end_ r = r.end_ let length r = Int64.succ (Int64.sub r.end_ r.start) let adjacent r1 r2 = Int64.succ r1.end_ = r2.start || Int64.succ r2.end_ = r1.start let overlaps r1 r2 = not (r1.end_ < r2.start || r2.end_ < r1.start) let contains r pos = pos >= r.start && pos <= r.end_ let merge r1 r2 = if overlaps r1 r2 || adjacent r1 r2 then Some { start = min r1.start r2.start; end_ = max r1.end_ r2.end_; } else None let compare r1 r2 = Int64.compare r1.start r2.start let to_string r = Printf.sprintf "%Ld-%Ld" r.start r.end_ let of_string s = try match String.split_on_char '-' s with | [start_s; end_s] -> let start = Int64.of_string start_s in let end_ = Int64.of_string end_s in Some (create ~start ~end_) | _ -> None with _ -> None let pp fmt r = Format.fprintf fmt "[%Ld-%Ld]" r.start r.end_