routers_grpc 0.1.0

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

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

use crate::services::RouteService;
use routers::Route;
use routers_codec::{Entry, Metadata};
#[cfg(feature = "telemetry")]
use tracing::Level;

#[tonic::async_trait]
impl<E, M> OptimiseService for RouteService<E, M>
where
    M: Metadata + 'static,
    E: Entry + '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.graph.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 }))
            },
        )
    }
}