Skip to content

Runs on Cloudflare Workers (wasm32) via an optional worker transport — turnkey via mise; want a PR? #44

@joeblew999

Description

@joeblew999

Hi! Thanks for google_maps — the trait-based request/transport split made the following much cleaner than I expected.

I've got the crate running inside a Cloudflare Worker (wasm32-unknown-unknown, workers-rs) and wanted to offer it back. Everything is additive and feature-gated — the default reqwest build is byte-for-byte unchanged — so existing users are unaffected.

Branch (work-in-progress fork): https://github.com/joeblew999/google_maps/tree/feat/cloudflare-workers

1. A standalone bug fix (independent of the Workers work)

--no-default-features builds currently fail to compile. In src/error.rs the HttpWithBody variant is ungated, but its field type HttpErrorStatus and its classify() match arm are both #[cfg(feature = "reqwest")]. Without reqwest that yields E0412/E0425 (missing type) + E0004 (non-exhaustive match). One-line fix — gate the variant to match:

#[cfg(feature = "reqwest")]   // <-- add this
#[error("HTTP error {status}: {body:?}")]
#[diagnostic(code(google_maps::http_with_body))]
HttpWithBody { status: HttpErrorStatus, body: String },

Happy to send this as a tiny standalone PR regardless of the rest.

2. Optional Cloudflare Workers transport

A worker feature, mutually alternative to reqwest, that supplies the central send methods via worker::Fetch instead of reqwest. Because query_string()/query_url() are already transport-agnostic and each execute() just delegates to Client::get_request()/post_request(), it's small and localised:

  • worker feature = ["dep:worker", "dep:http"]; reqwest also gains dep:http.
  • RequestHeaders::request_headers() returns http::HeaderMap instead of reqwest::header::HeaderMap (same re-exported type, so the reqwest path is unchanged).
  • New cfg(all(worker, not(reqwest))) modules implement get_request/post_request with the same signatures — so no per-API execute() changes. No rate limiter / backon retry on this path (Workers have no timer).
  • New worker-gated Error::Worker / Error::WorkerHttp variants.

Consumers use the normal API: client.geocoding().with_address("…").execute().await?worker::Fetch under the hood. A runnable example Worker (geocode / reverse / directions / Places New text search) is in examples/worker/.

3. Turnkey dev setup (so it's easy to try)

The fork ships a mise config that makes the whole thing one-command-ish:

mise install          # rust + wasm32 target + wrangler + worker-build + gcloud
mise run test         # native unit tests (unchanged) + the wasm32 worker build gate
mise run example:dev  # local `wrangler dev` for the example Worker

It even provisions a restricted Google Maps API key for you via gcloud (mise run gcloud:setup + mise run secret:google) so there's no Console clicking. There's also mise run test:cf-smoke (offline-ish transport check) and test:cf-live (asserts live results).

Verification so far: native default build + full unit-test suite unchanged & green; wasm32 build with worker features green; the example Worker returns live Google data through worker::Fetch.

Question

Would you like a PR — and if so, which scope?

  1. Just the error.rs fix (trivial, no new deps).
  2. The fix + the worker transport (adds an optional worker dependency + a wasm build path in CI).
  3. Neither — I'll keep it on the fork.

Totally fine either way; I'll maintain it on the fork if you'd rather not take on the wasm surface. Thanks again for the crate!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions