···2929 | None ->
3030 (* Guess MIME type from filename if available *)
3131 let path = Eio.Path.native_exn file in
3232+ let mime_map = [
3333+ (".json", Mime.json);
3434+ (".html", Mime.html);
3535+ (".xml", Mime.xml);
3636+ (".txt", Mime.text);
3737+ ] in
3238 let guessed =
3333- if String.ends_with ~suffix:".json" path then Mime.json
3434- else if String.ends_with ~suffix:".html" path then Mime.html
3535- else if String.ends_with ~suffix:".xml" path then Mime.xml
3636- else if String.ends_with ~suffix:".txt" path then Mime.text
3737- else Mime.octet_stream
3939+ List.find_map (fun (suffix, mime_type) ->
4040+ if String.ends_with ~suffix path then Some mime_type else None
4141+ ) mime_map
4242+ |> Option.value ~default:Mime.octet_stream
3843 in
3944 Log.debug (fun m -> m "Guessed MIME type %s for file %s" (Mime.to_string guessed) path);
4045 guessed
···4247 Log.debug (fun m -> m "Creating file body from %s with MIME type %s"
4348 (Eio.Path.native_exn file) (Mime.to_string mime));
4449 File { file; mime }
5050+5151+let json_encoding_error e =
5252+ let msg = Jsont.Error.to_string e in
5353+ failwith (Printf.sprintf "Failed to encode JSON: %s" msg)
45544655(* For simple JSON encoding, we just take a Jsont.json value and encode it *)
4756let json (json_value : Jsont.json) =
4857 let content = match Jsont_bytesrw.encode_string' ~format:Jsont.Minify Jsont.json json_value with
4958 | Ok s -> s
5050- | Error e ->
5151- let msg = Jsont.Error.to_string e in
5252- failwith (Printf.sprintf "Failed to encode JSON: %s" msg)
5959+ | Error e -> json_encoding_error e
5360 in
5461 String { content; mime = Mime.json }
5562···7885 (* Encode the entire JSON value to string with minified format *)
7986 let content = match Jsont_bytesrw.encode_string' ~format:Jsont.Minify Jsont.json json_value with
8087 | Ok s -> s
8181- | Error e ->
8282- let msg = Jsont.Error.to_string e in
8383- failwith (Printf.sprintf "Failed to encode JSON stream: %s" msg)
8888+ | Error e -> json_encoding_error e
8489 in
8590 let t = { Json_stream_source.content; offset = 0 } in
8691 let ops = Eio.Flow.Pi.source (module Json_stream_source) in
+10-22
lib/one.ml
···7878 (tcp_flow :> [`Close | `Flow | `R | `Shutdown | `W] Eio.Resource.t)
7979 in
80808181- match timeout with
8282- | Some t ->
8383- let timeout_seconds = Timeout.total t in
8484- (match timeout_seconds with
8585- | Some seconds ->
8686- Log.debug (fun m -> m "Setting connection timeout: %.2f seconds" seconds);
8787- Eio.Time.with_timeout_exn clock seconds connect_fn
8888- | None -> connect_fn ())
8181+ match Option.bind timeout Timeout.total with
8282+ | Some seconds ->
8383+ Log.debug (fun m -> m "Setting connection timeout: %.2f seconds" seconds);
8484+ Eio.Time.with_timeout_exn clock seconds connect_fn
8985 | None -> connect_fn ()
90869187(* Main request implementation - completely stateless *)
···10197 let headers = Option.value headers ~default:Headers.empty in
1029810399 (* Apply auth *)
104104- let headers = match auth with
105105- | Some a ->
106106- Log.debug (fun m -> m "Applying authentication");
107107- Auth.apply a headers
108108- | None -> headers
100100+ let headers = Option.fold ~none:headers auth ~some:(fun a ->
101101+ Log.debug (fun m -> m "Applying authentication");
102102+ Auth.apply a headers)
109103 in
110104111105 (* Add content type from body *)
112112- let headers = match body with
113113- | Some b -> (match Body.content_type b with
114114- | Some mime -> Headers.content_type mime headers
115115- | None -> headers)
116116- | None -> headers
106106+ let headers = Option.bind body Body.content_type
107107+ |> Option.fold ~none:headers ~some:(fun mime -> Headers.content_type mime headers)
117108 in
118109119110 (* Convert body to string for sending *)
120120- let request_body_str = match body with
121121- | None -> ""
122122- | Some b -> Body.Private.to_string b
123123- in
111111+ let request_body_str = Option.fold ~none:"" ~some:Body.Private.to_string body in
124112125113 (* Execute request with redirects *)
126114 let rec make_with_redirects url_to_fetch redirects_left =
+2-3
lib/response.ml
···3939let header name t = Headers.get name t.headers
40404141let content_type t =
4242- match Headers.get "content-type" t.headers with
4343- | None -> None
4444- | Some ct -> Some (Mime.of_string ct)
4242+ Headers.get "content-type" t.headers
4343+ |> Option.map Mime.of_string
45444645let content_length t =
4746 match Headers.get "content-length" t.headers with