geohash
A no_std-friendly Rust crate for encoding, decoding, and finding neighbors of geohash strings.
Repository Health
Technical Analysis
geohash is a compact Rust implementation of the geohash algorithm, the base32 encoding scheme that packs a latitude/longitude pair into a short, sortable string. It ports the logic of the popular node-geohash JavaScript library to Rust, exposing encode, decode, and neighbor-lookup functions built on the geo-types Coord and Rect primitives used across the georust ecosystem.
The crate is deliberately small: three source files handle the bit-interleaving math, the public error type, and directional neighbor lookups. It supports no_std environments out of the box, making it usable in embedded, WASM, or other allocation-constrained targets, and it ships an allocation-free encode_iter variant alongside the convenience encode function for callers who need to avoid heap allocation on hot paths.
What You Get
encode/decodefunctions to convert between aCoord<f64>and a geohash string of configurable length (1-12 characters)encode_iterfor allocation-free encoding when callers want to stream or truncate geohash characters themselvesdecode_bboxto recover the bounding box (as ageo_types::Rect) a geohash string represents, including its precision errorneighbor/neighborsto find the geohash(es) adjacent to a given hash in one or all eight compass directions- A
GeohashErrorenum (InvalidHashCharacter,InvalidCoordinateRange,InvalidLength,InvalidHash) implementing the standardErrortrait for explicit failure handling - Optional
no_stdsupport via thestdfeature flag, backed bylibmfor math functions unavailable in core
Common Use Cases
- Encoding user or device coordinates into a geohash for use as a database index or cache key that clusters nearby points together
- Decoding stored geohash strings back into coordinates and bounding boxes for map rendering or distance calculations
- Expanding a geohash into its neighbor set to build approximate radius/proximity search queries without a full geospatial index
- Embedded or WASM targets that need geohash encoding without pulling in the Rust standard library
Under The Hood
Architecture
The crate is a small, cleanly separated module set: core.rs holds the encode/decode bit-interleaving logic, neighbors.rs defines the Direction enum and Neighbors struct, and error.rs defines the shared GeohashError type, with lib.rs re-exporting the public surface and re-exporting Coord/Rect from geo_types. There is no runtime state, dependency injection, or I/O — every function is a pure transformation over its inputs, which makes the public API easy to reason about but also means every consumer of encode/decode sits directly on top of the spread/squash/interleave bit-math helpers in core.rs; a change to that interleaving scheme would break encode, decode, and neighbor lookups simultaneously since neighbor is itself implemented in terms of decode and encode.
Tech Stack
Built on 2018-edition Rust with no_std support (#![cfg_attr(not(feature = "std"), no_std)]), the crate depends on geo-types (with default-features = false) for its Coord/Rect types and on libm for the ldexp computation used when the standard library isn’t available. Dev-dependencies (csv, num-traits, serde) support the test and benchmark suites only. There is no build step beyond Cargo; CI (GitHub Actions) runs cargo fmt --check, cargo test both with and without default features, and cargo clippy across stable and nightly toolchains, and the crate publishes its API docs to docs.rs.
Code Quality
The crate ships a dedicated tests/base.rs suite alongside a testcases.csv fixture for round-trip encode/decode verification, plus a benches/base.rs performance benchmark, and nearly every public function carries runnable rustdoc examples with assert_eq! checks that double as documentation tests. Errors are explicit and typed through GeohashError rather than panics on invalid input, and the CI pipeline enforces rustfmt and clippy on every change across both feature-flag configurations, giving reasonable confidence in correctness for a project of this size.
What Makes It Unique
The algorithm itself (geohash, ported from node-geohash) is well established, but the implementation favors performance and portability: spread/squash/deinterleave use branchless bit-shifting lookup tables rather than naive per-bit loops, encode_iter offers an allocation-free path for hot loops, and full no_std compatibility lets the crate run in embedded or WASM contexts where the georust ecosystem’s other spatial crates it interoperates with via geo-types might not otherwise be usable.