w3w_api/
api.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::Error;
6
7#[derive(Debug, Deserialize, Serialize)]
8#[serde(untagged)]
9pub enum ApiResponse<T> {
10    Error { error: ErrorResponse },
11    Ok(T),
12}
13
14impl<T> Into<Result<T, Error>> for ApiResponse<T> {
15    fn into(self) -> Result<T, Error> {
16        match self {
17            ApiResponse::Error { error } => Err(Error::Api(error)),
18            ApiResponse::Ok(inner) => Ok(inner),
19        }
20    }
21}
22
23#[derive(Debug, Deserialize, Serialize)]
24pub struct ErrorResponse {
25    pub code: ErrorCode,
26    pub message: String,
27}
28
29#[derive(Debug, Deserialize, Serialize)]
30#[non_exhaustive]
31pub enum ErrorCode {
32    // 400 Bad Request
33    BadWords,
34    BadCoordinates,
35    BadLanguage,
36    BadFormat,
37    BadClipToPolygon,
38    MissingWords,
39    MissingInput,
40    MissingBoundingBox,
41    DuplicateParameter,
42
43    // 401 Unauthorized
44    MissingKey,
45    InvalidKey,
46
47    // 404 Not Found
48    NotFound,
49
50    // 405 Method Not Allowed
51    MethodNotAllowed,
52
53    // 500 Internal Server Error
54    InternalServerError,
55}
56
57#[derive(Debug, Deserialize, Serialize)]
58pub struct Coords {
59    pub country: String,
60    pub square: Square,
61    pub nearest_place: Option<String>,
62    pub coordinates: GeoCoords,
63    pub words: String,
64    pub language: String,
65    pub map: url::Url,
66}
67
68impl fmt::Display for Coords {
69    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70        write!(f, "{}", self.coordinates)
71    }
72}
73
74#[derive(Debug, Deserialize, Serialize)]
75pub struct Square {
76    pub southwest: GeoCoords,
77    pub northeast: GeoCoords,
78}
79
80#[derive(Debug, Deserialize, Serialize)]
81pub struct GeoCoords {
82    pub lat: f64,
83    pub lng: f64,
84}
85
86impl Into<geo_types::Point<f64>> for GeoCoords {
87    fn into(self) -> geo_types::Point<f64> {
88        geo_types::Point::new(self.lng, self.lat)
89    }
90}
91
92impl fmt::Display for GeoCoords {
93    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94        write!(f, "{},{}", self.lat, self.lng)
95    }
96}
97
98#[derive(Debug, Deserialize, Serialize)]
99pub struct AvailableLanguages {
100    pub languages: Vec<Language>,
101}
102
103impl fmt::Display for AvailableLanguages {
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        write!(
106            f,
107            "{}",
108            self.languages
109                .iter()
110                .map(|lang| lang.to_string())
111                .collect::<Vec<_>>()
112                .join(",")
113        )
114    }
115}
116#[derive(Debug, Deserialize, Serialize)]
117#[serde(rename_all = "camelCase")]
118pub struct Language {
119    code: String,
120    name: String,
121    native_name: String,
122}
123
124impl fmt::Display for Language {
125    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126        write!(f, "{} ({})", self.name, self.code)
127    }
128}