1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Crate ruma_api contains core types used to define the requests and responses for each endpoint
//! in the various [Matrix](https://matrix.org) API specifications.
//! These types can be shared by client and server code for all Matrix APIs.
//!
//! When implementing a new Matrix API, each endpoint have a type that implements `Endpoint`, plus
//! any necessary associated types.
//! An implementation of `Endpoint` contains all the information about the HTTP method, the path and
//! input parameters for requests, and the structure of a successful response.
//! Such types can then be used by client code to make requests, and by server code to fulfill
//! those requests.
//!
//! # Example
//!
//! ```rust,no_run
//! # #![feature(proc_macro)]
//! #
//! # extern crate ruma_api;
//! # extern crate ruma_identifiers;
//! # #[macro_use]
//! # extern crate serde_derive;
//! #
//! # fn main() {
//! /// PUT /_matrix/client/r0/directory/room/:room_alias
//! pub mod create {
//!     use ruma_api;
//!     use ruma_identifiers::{RoomAliasId, RoomId};
//!
//!     /// This API endpoint's body parameters.
//!     #[derive(Clone, Debug, Deserialize, Serialize)]
//!     pub struct BodyParams {
//!         pub room_id: RoomId,
//!     }
//!
//!     /// This API endpoint's path parameters.
//!     #[derive(Clone, Debug)]
//!     pub struct PathParams {
//!         pub room_alias: RoomAliasId,
//!     }
//!
//!     /// Details about this API endpoint.
//!     pub struct Endpoint;
//!
//!     impl ruma_api::Endpoint for Endpoint {
//!         type BodyParams = BodyParams;
//!         type PathParams = PathParams;
//!         type QueryParams = ();
//!         type Response = ();
//!
//!         fn method() -> ruma_api::Method {
//!             ruma_api::Method::Put
//!         }
//!
//!         fn request_path(params: Self::PathParams) -> String {
//!             format!("/_matrix/client/r0/directory/room/{}", params.room_alias)
//!         }
//!
//!         fn router_path() -> &'static str {
//!             "/_matrix/client/r0/directory/room/:room_alias"
//!         }
//!
//!         fn name() -> &'static str {
//!             "room_directory"
//!         }
//!
//!         fn description() -> &'static str {
//!             "Matrix implementation of room directory."
//!         }
//!
//!         fn requires_authentication() -> bool {
//!             true
//!         }
//!
//!         fn rate_limited() -> bool {
//!             false
//!         }
//!     }
//! }
//! # }

#![deny(missing_docs)]

extern crate serde;

use serde::{Deserialize, Serialize};

/// HTTP request methods used in Matrix APIs.
#[derive(Clone, Copy, Debug)]
pub enum Method {
    /// DELETE
    Delete,
    /// GET
    Get,
    /// POST
    Post,
    /// PUT
    Put,
}

/// An API endpoint.
pub trait Endpoint {
    /// Request parameters supplied via the body of the HTTP request.
    type BodyParams: Deserialize + Serialize;

    /// Request parameters supplied via the URL's path.
    type PathParams;

    /// Parameters supplied via the URL's query string.
    type QueryParams: Deserialize + Serialize;

    /// The body of the response.
    type Response: Deserialize + Serialize;

    /// Returns the HTTP method used by this endpoint.
    fn method() -> Method;

    /// Generates the path component of the URL for this endpoint using the supplied parameters.
    fn request_path(params: Self::PathParams) -> String;

    /// Generates a generic path component of the URL for this endpoint, suitable for `Router` from
    /// the router crate.
    fn router_path() -> &'static str;

    /// A unique identifier for this endpoint, suitable for `Router` from the router crate.
    fn name() -> &'static str;

    /// A human-readable description of the endpoint.
    fn description() -> &'static str;

    /// Whether or not this endpoint requires an authenticated user.
    fn requires_authentication() -> bool;

    /// Whether or not this endpoint is rate limited.
    fn rate_limited() -> bool;
}