Properly send errors in api
This commit is contained in:
parent
d6f1506b31
commit
83932cc297
@ -12,6 +12,8 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
s2 = {version="0.0.12", default-features=false}
|
s2 = {version="0.0.12", default-features=false}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use rocket::{get, routes, serde::json::Json};
|
use rocket::{get, routes, serde::json::Json, Responder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use this_algorithm::Address;
|
use this_algorithm::Address;
|
||||||
|
|
||||||
@ -18,20 +18,30 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/address?<lat>&<lon>")]
|
#[get("/address?<lat>&<lon>")]
|
||||||
async fn get_address(lat: f64, lon: f64) -> Result<String, String> {
|
async fn get_address(lat: Option<String>, lon: Option<String>) -> Result<String, ApiError> {
|
||||||
Address::from_lat_lon(lat, lon)
|
let (lat, lon) = lat.zip(lon).ok_or(ApiError::InvalidRequest(
|
||||||
.map(|a| a.to_string())
|
"lat and lon parameters are required",
|
||||||
.map_err(|e| e.to_string())
|
))?;
|
||||||
|
let lat = lat
|
||||||
|
.parse::<f64>()
|
||||||
|
.map_err(|_| ApiError::InvalidRequest("Invalid lat parameter"))?;
|
||||||
|
let lon = lon
|
||||||
|
.parse::<f64>()
|
||||||
|
.map_err(|_| ApiError::InvalidRequest("Invalid lon parameter"))?;
|
||||||
|
|
||||||
|
Ok(Address::from_lat_lon(lat, lon)?.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/coords?<address>")]
|
#[get("/coords?<address>")]
|
||||||
async fn get_coords(address: String) -> Result<Json<Coords>, String> {
|
async fn get_coords(address: Option<String>) -> Result<Json<Coords>, ApiError> {
|
||||||
|
let address = address.ok_or(ApiError::InvalidRequest("address parameter required"))?;
|
||||||
|
|
||||||
Address::from_str(&address)
|
Address::from_str(&address)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
.map_err(Into::into)
|
||||||
.map(Address::to_lat_lon)
|
.map(Address::to_lat_lon)
|
||||||
.map(Coords::from)
|
.map(Coords::from)
|
||||||
.map(Json)
|
.map(Json)
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@ -45,3 +55,24 @@ impl From<(f64, f64)> for Coords {
|
|||||||
Self { lat, lon }
|
Self { lat, lon }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(status = 400)]
|
||||||
|
enum ApiError {
|
||||||
|
#[response(status = 400)]
|
||||||
|
AlgorithmError(String),
|
||||||
|
#[response(status = 400)]
|
||||||
|
InvalidRequest(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&this_algorithm::Error> for ApiError {
|
||||||
|
fn from(e: &this_algorithm::Error) -> Self {
|
||||||
|
Self::AlgorithmError(e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<this_algorithm::Error> for ApiError {
|
||||||
|
fn from(e: this_algorithm::Error) -> Self {
|
||||||
|
Self::from(&e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user