routers_grpc 0.1.2

gRPC Endpoints for Routers
Documentation
use alloc::sync::Arc;
use geo::{Point, coord};
use routers_network::Network;
use tonic::{Request, Response, Status};

use crate::definition::model::*;
use crate::definition::optimise::*;

use crate::services::GrpcAdapter;
use routers_network::{Entry, Metadata};

#[cfg(feature = "telemetry")]
use tracing::Level;

#[tonic::async_trait]
impl<T, E, M> OptimiseService for GrpcAdapter<T, E, M>
where
    T: Network<E, M> + Send + Sync + 'static,
    M: Metadata + Send + Sync + 'static,
    E: Entry + Send + Sync + 'static,
{
    #[cfg_attr(feature="telemetry", tracing::instrument(skip_all, err(level = Level::INFO)))]
    async fn route(
        self: Arc<Self>,
        request: Request<RouteRequest>,
    ) -> Result<Response<RouteResponse>, Status> {
        let (_, _, routing) = request.into_parts();

        let start = routing
            .start
            .map_or(
                Err(Status::invalid_argument("Missing Start Coordinate")),
                |v| Ok(coord! { x: v.longitude, y: v.latitude }),
            )
            .map_err(|err| Status::internal(format!("{err:?}")))?;

        let end = routing
            .end
            .map_or(
                Err(Status::invalid_argument("Missing End Coordinate")),
                |v| Ok(coord! { x: v.longitude, y: v.latitude }),
            )
            .map_err(|err| Status::internal(format!("{err:?}")))?;

        self.inner.route_points(&Point(start), &Point(end)).map_or(
            Err(Status::internal("Could not route")),
            |(cost, route)| {
                let shape = route
                    .iter()
                    .map(|node| Coordinate {
                        latitude: node.position.y(),
                        longitude: node.position.x(),
                    })
                    .collect();

                Ok(Response::new(RouteResponse { cost, shape }))
            },
        )
    }
}