Rust
BGrid for Rust
A safe, idiomatic Rust implementation of the BGrid protocol. It provides strongly-typed conversions between geographic coordinates and BGrid indices with comprehensive error handling via Result types. The single-file library has minimal dependencies and is suitable for CLI tools, backend services, and WebAssembly targets.
Features
- Minimal Dependencies: Only depends on
serde_jsonfor wordlist parsing. - Strongly Typed: All functions return
Result<T, BGridError>with descriptive error variants. - Safe: No
unsafecode; all operations are bounds-checked. - BIP39 Word Support: Encode and decode grid indices as human-readable words in 9 languages.
- Cross-Platform: Works on any target supported by the Rust toolchain, including WASM.
- Test Vector Parity: Passes the same test vectors as the JavaScript implementation.
Installation
Add bgrid to your Cargo.toml:
[dependencies]
bgrid = "0.1"
Or via the command line:
cargo add bgrid
Source repository:
git clone https://github.com/bgrid-maps/bgrid-rust.git
Quick Start
use std::path::Path;
use bgrid::{coords_to_bgrid, bgrid_to_cell, load_language, grid_to_display, DisplayMode};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Encode coordinates to BGrid indices
let grid = coords_to_bgrid(40.7128, -74.0060, 3)?;
println!("{:?}", grid); // [531, 1563, 1600]
// Decode back to cell center and bounds
let cell = bgrid_to_cell(&grid)?;
println!("Center: ({}, {})", cell.lat, cell.lon);
println!("Bounds: {:?}", cell.bounds);
// Display as numbers
let display = grid_to_display(&grid, DisplayMode::Numbers, None)?;
println!("{}", display); // "531,1563,1600"
// Display as BIP39 words
let words = load_language("en", Path::new("bip39-wordlist"))?;
let display = grid_to_display(&grid, DisplayMode::Words, Some(&words))?;
println!("{}", display); // "word1,word2,word3"
Ok(())
}
API Reference
Types
Cell
Represents a decoded BGrid cell with its center point and geographic bounds.
pub struct Cell {
pub lat: f64, // Center latitude
pub lon: f64, // Center longitude
pub bounds: [[f64; 2]; 2], // [[minLat, minLon], [maxLat, maxLon]]
}
GridCell
Represents a cell within a hierarchical grid query, including its full path.
pub struct GridCell {
pub index: u16, // Cell index at this level (1–2048)
pub grid: Vec<u16>, // Full grid path from root
pub center: (f64, f64), // (latitude, longitude)
pub bounds: [[f64; 2]; 2], // [[minLat, minLon], [maxLat, maxLon]]
}
DisplayMode
Controls the output format of grid_to_display.
pub enum DisplayMode {
Numbers, // Comma-separated numeric indices
Words, // Comma-separated BIP39 words
}
BGridError
Error type returned by all fallible functions.
pub enum BGridError {
InvalidLatLon, // lat/lon must be finite
InvalidLevels, // levels must be a positive integer
InvalidGrid, // bgrid array must be non-empty with valid indices
InvalidLanguage(String), // unsupported language code
InvalidWords, // word list must contain exactly 2048 entries
MissingWords, // word list required for Words display mode
Io(String), // file I/O error
Json(String), // JSON parsing error
}
Functions
coords_to_bgrid
Converts geographic coordinates to a BGrid index vector.
pub fn coords_to_bgrid(lat: f64, lon: f64, levels: usize) -> Result<Vec<u16>, BGridError>
| Parameter | Type | Description |
|---|---|---|
lat | f64 | Latitude (-90 to 90), must be finite |
lon | f64 | Longitude (-180 to 180), must be finite |
levels | usize | Positive integer for subdivision depth |
Returns: Vec<u16> of 1-based grid indices (1–2048 per level).
Errors: InvalidLatLon if coordinates are not finite; InvalidLevels if levels is 0.
bgrid_to_cell
Converts a BGrid index slice back to geographic bounds and center.
pub fn bgrid_to_cell(bgrid: &[u16]) -> Result<Cell, BGridError>
| Parameter | Type | Description |
|---|---|---|
bgrid | &[u16] | Slice of grid indices (1–2048) |
Returns: Cell with center coordinates and bounding box.
Errors: InvalidGrid if the slice is empty or contains out-of-range indices.
get_grid_cells
Generates all sub-cells for a given level under a parent grid.
pub fn get_grid_cells(
level: usize,
parent_grid: &[u16],
max_level: usize,
) -> Result<Vec<GridCell>, BGridError>
| Parameter | Type | Description |
|---|---|---|
level | usize | Target level (1+) |
parent_grid | &[u16] | Parent grid path for sub-queries |
max_level | usize | Maximum level to generate |
Returns: Vec<GridCell> containing all cells at the specified level.
load_language
Loads a BIP39 wordlist from a JSON file on disk.
pub fn load_language(lang: &str, base_path: &Path) -> Result<Vec<String>, BGridError>
| Parameter | Type | Description |
|---|---|---|
lang | &str | Language code (e.g. "en", "es", "ja") |
base_path | &Path | Directory containing bip39-*.json files |
Returns: Vec<String> of 2048 words.
Errors: InvalidLanguage if code is unsupported; Io / Json for file or parsing failures; InvalidWords if the list does not contain exactly 2048 entries.
number_to_word
Converts a single grid index to its BIP39 word.
pub fn number_to_word(number: u16, words: &[String]) -> Option<&str>
| Parameter | Type | Description |
|---|---|---|
number | u16 | Grid index (1–2048) |
words | &[String] | Word list from load_language |
Returns: Some(&str) with the word, or None if out of range.
word_to_number
Converts a BIP39 word to its grid index.
pub fn word_to_number(word: &str, words: &[String]) -> Option<u16>
| Parameter | Type | Description |
|---|---|---|
word | &str | BIP39 word (case-insensitive lookup) |
words | &[String] | Word list from load_language |
Returns: Some(u16) with the 1-based index, or None if not found.
grid_to_display
Formats a grid index slice as a display string.
pub fn grid_to_display(
grid: &[u16],
mode: DisplayMode,
words: Option<&[String]>,
) -> Result<String, BGridError>
| Parameter | Type | Description |
|---|---|---|
grid | &[u16] | Slice of grid indices |
mode | DisplayMode | Numbers or Words |
words | Option<&[String]> | Required when mode is Words |
Returns: Comma-separated string.
Errors: MissingWords if mode is Words and no word list provided; InvalidWords if list is not 2048 entries.
Constants
SUPPORTED_LANGS
pub const SUPPORTED_LANGS: [&str; 9]
Array of supported language codes: ["cs", "en", "es", "fr", "it", "ja", "ko", "pt", "zh"].
BIP39 Word Support
The library supports 9 languages for BIP39 word encoding:
cs, en, es, fr, it, ja, ko, pt, zh
Word lists are loaded from JSON files via load_language(). Each file must contain a JSON array of exactly 2048 strings.
Resources
- Source Code: GitHub Repository
- Crates.io: bgrid