diff --git a/src/core/CCResult.ml b/src/core/CCResult.ml index 9e4228ea..c5283735 100644 --- a/src/core/CCResult.ml +++ b/src/core/CCResult.ml @@ -31,6 +31,22 @@ let fail_fprintf format = (fun out -> Format.pp_print_flush out (); fail (Buffer.contents buf)) out format +let add_ctx msg x = match x with + | Error e -> Error (e ^ "\ncontext:" ^ msg) + | Ok x -> Ok x + +let add_ctxf msg = + let buf = Buffer.create 64 in + let out = Format.formatter_of_buffer buf in + Format.kfprintf + (fun out e -> Format.pp_print_flush out (); add_ctx (Buffer.contents buf) e) + out msg + +(*$= + (Error "error\ncontext:message(number 42, foo: true)") \ + (add_ctxf "message(number %d, foo: %B)" 42 true (Error "error")) +*) + let of_exn e = let msg = Printexc.to_string e in Error msg diff --git a/src/core/CCResult.mli b/src/core/CCResult.mli index f236274c..9dc02bad 100644 --- a/src/core/CCResult.mli +++ b/src/core/CCResult.mli @@ -42,6 +42,20 @@ val fail_fprintf : ('a, Format.formatter, unit, ('a, string) t) format4 -> 'a (** [fail_printf format] uses [format] to obtain an error message and then returns [Error msg] *) +val add_ctx : string -> ('a, string) t -> ('a, string) t +(** [add_ctx msg] leaves [Ok x] untouched, but transforms + [Error s] into [Error s'] where [s'] contains the additional + context given by [msg] + @since NEXT_RELEASE *) + +val add_ctxf : ('a, Format.formatter, unit, ('b, string) t -> ('b, string) t) format4 -> 'a +(** [add_ctxf format_message] is similar to {!add_ctx} but with + {!Format} for printing the message (eagerly). + Example: {[ + add_ctxf "message(number %d, foo: %B)" 42 true (Error "error)" + ]} + @since NEXT_RELEASE *) + val map : ('a -> 'b) -> ('a, 'err) t -> ('b, 'err) t (** Map on success *)