Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ use solverforge_maps::{BoundingBox, Coord, NetworkConfig, RoadNetwork, RoutingRe
#[tokio::main]
async fn main() -> RoutingResult<()> {
let locations = vec![
Coord::new(39.95, -75.16),
Coord::new(39.96, -75.17),
Coord::try_new(39.95, -75.16)?,
Coord::try_new(39.96, -75.17)?,
];

let bbox = BoundingBox::from_coords(&locations).expand_for_routing(&locations);
Expand All @@ -59,18 +59,18 @@ Geographic coordinate with latitude and longitude. Validates input on constructi
```rust
use solverforge_maps::{Coord, CoordError};

// Panics on invalid input (NaN, infinite, out of range)
let coord = Coord::new(39.95, -75.16);
// Use try_new for external or user-provided input
let coord = Coord::try_new(39.95, -75.16)?;

// Fallible construction
let coord: Result<Coord, CoordError> = Coord::try_new(91.0, -75.16);
assert!(matches!(coord, Err(CoordError::LatOutOfRange { .. })));

// Valid ranges: lat [-90, 90], lng [-180, 180]
let coord = Coord::try_new(39.95, -75.16).unwrap();
// Coord::new is still fine for trusted literals that are guaranteed valid
let trusted_coord = Coord::new(39.95, -75.16);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Rebind coord to a Coord before the later example calls

Replacing the old let coord = Coord::try_new(...).unwrap(); with let trusted_coord = Coord::new(...) leaves coord bound to the Result<Coord, CoordError> from a few lines above. The subsequent coord.distance_to(other) and coord.into() therefore no longer type-check, so the public Coord example in the README regressed from copy-pastable to uncompilable.

Useful? React with 👍 / 👎.


// Distance calculation
let other = Coord::new(39.96, -75.17);
let other = Coord::try_new(39.96, -75.17)?;
let distance_meters = coord.distance_to(other);

// Tuple conversion
Expand Down Expand Up @@ -100,17 +100,17 @@ Rectangular geographic region. Validates that min < max on construction.
```rust
use solverforge_maps::{BoundingBox, BBoxError, Coord};

// Panics if min > max
let bbox = BoundingBox::new(39.9, -75.2, 40.0, -75.1);
// Use try_new when bounds come from external input
let bbox = BoundingBox::try_new(39.9, -75.2, 40.0, -75.1)?;

// Fallible construction
let bbox: Result<BoundingBox, BBoxError> = BoundingBox::try_new(40.0, -75.2, 39.9, -75.1);
assert!(matches!(bbox, Err(BBoxError::MinLatGreaterThanMax { .. })));

// From coordinates
let locations = vec![
Coord::new(39.95, -75.16),
Coord::new(39.96, -75.17),
Coord::try_new(39.95, -75.16)?,
Coord::try_new(39.96, -75.17)?,
];
let bbox = BoundingBox::from_coords(&locations);

Expand All @@ -121,9 +121,12 @@ let expanded = bbox.expand_for_routing(&locations); // Smart expansion (1.4x d

// Queries
let center: Coord = bbox.center();
let contains: bool = bbox.contains(Coord::new(39.95, -75.15));
let contains: bool = bbox.contains(Coord::try_new(39.95, -75.15)?);
```

`BoundingBox::new` remains appropriate when the bounds are compile-time literals
or otherwise already validated before construction.

#### BBoxError

```rust
Expand Down Expand Up @@ -198,7 +201,7 @@ Core routing engine built from OSM data.
```rust
use solverforge_maps::{BoundingBox, NetworkConfig, RoadNetwork, NetworkRef};

let bbox = BoundingBox::new(39.9, -75.2, 40.0, -75.1);
let bbox = BoundingBox::try_new(39.9, -75.2, 40.0, -75.1)?;
let config = NetworkConfig::default();

// Load from cache or fetch from API (returns cached reference)
Expand All @@ -221,8 +224,8 @@ than at snapped nodes, use `snap_to_edge` with `route_edge_snapped`.
```rust
use solverforge_maps::{Coord, Objective, RouteResult, RoutingError};

let from = Coord::new(39.95, -75.16);
let to = Coord::new(39.96, -75.17);
let from = Coord::try_new(39.95, -75.16)?;
let to = Coord::try_new(39.96, -75.17)?;

// Route by minimum travel time (default). Endpoints are snapped to nearest nodes.
let route: Result<RouteResult, RoutingError> = network.route(from, to);
Expand All @@ -248,8 +251,8 @@ nearest road segments instead of the nearest graph nodes.
```rust
use solverforge_maps::{Coord, RouteResult, RoutingError};

let from = Coord::new(39.95, -75.16);
let to = Coord::new(39.96, -75.17);
let from = Coord::try_new(39.95, -75.16)?;
let to = Coord::try_new(39.96, -75.17)?;

let from_edge = network.snap_to_edge(from)?;
let to_edge = network.snap_to_edge(to)?;
Expand All @@ -261,7 +264,7 @@ let route: Result<RouteResult, RoutingError> = network.route_edge_snapped(&from_
```rust
use solverforge_maps::{Coord, SnappedCoord, RoutingError};

let coord = Coord::new(39.95, -75.16);
let coord = Coord::try_new(39.95, -75.16)?;

// Simple snap (returns None if network is empty)
let node = network.snap_to_road(coord);
Expand Down Expand Up @@ -306,9 +309,9 @@ Travel time matrix with metadata and analysis methods.
use solverforge_maps::{Coord, TravelTimeMatrix, UNREACHABLE};

let locations = vec![
Coord::new(39.95, -75.16),
Coord::new(39.96, -75.17),
Coord::new(39.94, -75.15),
Coord::try_new(39.95, -75.16)?,
Coord::try_new(39.96, -75.17)?,
Coord::try_new(39.94, -75.15)?,
];

// Compute matrix (async, parallel via rayon internally)
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
//! #[tokio::main]
//! async fn main() -> RoutingResult<()> {
//! let locations = vec![
//! Coord::new(39.95, -75.16),
//! Coord::new(39.96, -75.17),
//! Coord::try_new(39.95, -75.16)?,
//! Coord::try_new(39.96, -75.17)?,
//! ];
//!
//! let bbox = BoundingBox::from_coords(&locations).expand(0.1);
Expand Down
Loading