Add 'ruma-client-api/' from commit '632eb9d520028816c5fb7224bd0aca8d1e3793f1'
git-subtree-dir: ruma-client-api git-subtree-mainline: e5233c49f610f866e3c9bf8529a0613171fc2fe4 git-subtree-split: 632eb9d520028816c5fb7224bd0aca8d1e3793f1
This commit is contained in:
		
						commit
						6329cd471e
					
				
							
								
								
									
										30
									
								
								ruma-client-api/.builds/beta.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/.builds/beta.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | image: archlinux | ||||||
|  | packages: | ||||||
|  |   - rustup | ||||||
|  | sources: | ||||||
|  |   - https://github.com/ruma/ruma-client-api | ||||||
|  | tasks: | ||||||
|  |   - rustup: | | ||||||
|  |       # We specify --profile minimal because we'd otherwise download docs | ||||||
|  |       rustup toolchain install beta --profile minimal -c rustfmt -c clippy | ||||||
|  |       rustup default beta | ||||||
|  |   - test: | | ||||||
|  |       cd ruma-client-api | ||||||
|  | 
 | ||||||
|  |       # We don't want the build to stop on individual failure of independent | ||||||
|  |       # tools, so capture tool exit codes and set the task exit code manually | ||||||
|  |       set +e | ||||||
|  | 
 | ||||||
|  |       cargo fmt -- --check | ||||||
|  |       fmt_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo clippy --all-targets --all-features -- -D warnings | ||||||
|  |       clippy_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo test --no-default-features --verbose | ||||||
|  |       test1_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo test --all-features --verbose | ||||||
|  |       test2_exit=$? | ||||||
|  | 
 | ||||||
|  |       exit $(( $fmt_exit || $clippy_exit || $test1_exit || $test2_exit )) | ||||||
							
								
								
									
										26
									
								
								ruma-client-api/.builds/msrv.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								ruma-client-api/.builds/msrv.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | image: archlinux | ||||||
|  | packages: | ||||||
|  |   - rustup | ||||||
|  | sources: | ||||||
|  |   - https://github.com/ruma/ruma-client-api | ||||||
|  | tasks: | ||||||
|  |   - rustup: | | ||||||
|  |       # We specify --profile minimal because we'd otherwise download docs | ||||||
|  |       rustup toolchain install 1.40.0 --profile minimal | ||||||
|  |       rustup default 1.40.0 | ||||||
|  |   - test: | | ||||||
|  |       cd ruma-client-api | ||||||
|  | 
 | ||||||
|  |       # We don't want the build to stop on individual failure of independent | ||||||
|  |       # tools, so capture tool exit codes and set the task exit code manually | ||||||
|  |       set +e | ||||||
|  | 
 | ||||||
|  |       # Only make sure the code builds with the MSRV. Tests can require later | ||||||
|  |       # Rust versions, don't compile or run them. | ||||||
|  |       cargo build --no-default-features --verbose | ||||||
|  |       build1_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo build --all-features --verbose | ||||||
|  |       build2_exit=$? | ||||||
|  | 
 | ||||||
|  |       exit $(( $build1_exit || $build2_exit )) | ||||||
							
								
								
									
										32
									
								
								ruma-client-api/.builds/nightly.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ruma-client-api/.builds/nightly.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | image: archlinux | ||||||
|  | packages: | ||||||
|  |   - rustup | ||||||
|  | sources: | ||||||
|  |   - https://github.com/ruma/ruma-client-api | ||||||
|  | tasks: | ||||||
|  |   - rustup: | | ||||||
|  |       rustup toolchain install nightly --profile minimal | ||||||
|  |       rustup default nightly | ||||||
|  | 
 | ||||||
|  |       # Try installing rustfmt & clippy for nightly, but don't fail the build | ||||||
|  |       # if they are not available | ||||||
|  |       rustup component add rustfmt || true | ||||||
|  |       rustup component add clippy || true | ||||||
|  |   - test: | | ||||||
|  |       cd ruma-client-api | ||||||
|  | 
 | ||||||
|  |       # We don't want the build to stop on individual failure of independent | ||||||
|  |       # tools, so capture tool exit codes and set the task exit code manually | ||||||
|  |       set +e | ||||||
|  | 
 | ||||||
|  |       if ( rustup component list | grep -q rustfmt ); then | ||||||
|  |         cargo fmt -- --check | ||||||
|  |       fi | ||||||
|  |       fmt_exit=$? | ||||||
|  | 
 | ||||||
|  |       if ( rustup component list | grep -q clippy ); then | ||||||
|  |         cargo clippy --all-targets --all-features -- -D warnings | ||||||
|  |       fi | ||||||
|  |       clippy_exit=$? | ||||||
|  | 
 | ||||||
|  |       exit $(( $fmt_exit || $clippy_exit )) | ||||||
							
								
								
									
										32
									
								
								ruma-client-api/.builds/stable.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ruma-client-api/.builds/stable.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | image: archlinux | ||||||
|  | packages: | ||||||
|  |   - rustup | ||||||
|  | sources: | ||||||
|  |   - https://github.com/ruma/ruma-client-api | ||||||
|  | tasks: | ||||||
|  |   - rustup: | | ||||||
|  |       # We specify --profile minimal because we'd otherwise download docs | ||||||
|  |       rustup toolchain install stable --profile minimal -c rustfmt -c clippy | ||||||
|  |       rustup default stable | ||||||
|  |   - test: | | ||||||
|  |       cd ruma-client-api | ||||||
|  | 
 | ||||||
|  |       # We don't want the build to stop on individual failure of independent | ||||||
|  |       # tools, so capture tool exit codes and set the task exit code manually | ||||||
|  |       set +e | ||||||
|  | 
 | ||||||
|  |       cargo fmt -- --check | ||||||
|  |       fmt_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo clippy --all-targets --all-features -- -D warnings | ||||||
|  |       clippy_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo test --no-default-features --verbose | ||||||
|  |       test1_exit=$? | ||||||
|  | 
 | ||||||
|  |       cargo test --all-features --verbose | ||||||
|  |       test2_exit=$? | ||||||
|  | 
 | ||||||
|  |       exit $(( $fmt_exit || $clippy_exit || $test1_exit || $test2_exit )) | ||||||
|  |   # TODO: Add audit task once cargo-audit binary releases are available. | ||||||
|  |   #       See https://github.com/RustSec/cargo-audit/issues/66 | ||||||
							
								
								
									
										2
									
								
								ruma-client-api/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								ruma-client-api/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | Cargo.lock | ||||||
|  | target | ||||||
							
								
								
									
										202
									
								
								ruma-client-api/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								ruma-client-api/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,202 @@ | |||||||
|  | # [unreleased] | ||||||
|  | 
 | ||||||
|  | Breaking changes: | ||||||
|  | 
 | ||||||
|  | * Make `avatar_url` in `r0::profile::set_avatar_url::Request` an `Option` | ||||||
|  | * Update type of `canonical_alias` in `r0::directory::PublicRoomsChunk` from | ||||||
|  |   `Option<String>` to `Option<RoomAliasId>` | ||||||
|  | * Update `r0::room::create_room::CreationContent` | ||||||
|  |   * Change `federated`s type from `Option<bool>` to `bool` | ||||||
|  |   * Add `predecessor` field | ||||||
|  | * Update `r0::push::get_pushrules_all` and `r0::push::get_pushrules_global_scope` to use the | ||||||
|  |   `Ruleset` type from `ruma_events` | ||||||
|  | * Fix event types in `r0::context::get_context` | ||||||
|  | 
 | ||||||
|  | Improvements: | ||||||
|  | 
 | ||||||
|  | * Add method `into_event_content` for `r0::room::create_room::CreationContent` | ||||||
|  | * Add room visibility endpoints: `r0::directory::{get_room_visibility, set_room_visibility}`. | ||||||
|  | 
 | ||||||
|  | Deprecations: | ||||||
|  | 
 | ||||||
|  | * `r0::sync::sync_events::SetPresence` has been renamed to `PresenceState`. It is still available | ||||||
|  |   under its previous name, but only for one release. | ||||||
|  | 
 | ||||||
|  | # 0.9.0 | ||||||
|  | 
 | ||||||
|  | Bug fixes: | ||||||
|  | 
 | ||||||
|  | * Fix (de)serialization for `r0::media::get_content_thumnail::Response` | ||||||
|  | * Make `r0::device::get_devices::Response::devices` public | ||||||
|  | 
 | ||||||
|  | Breaking changes: | ||||||
|  | 
 | ||||||
|  | * The `event_id` in the response for the message and state sending endpoints is now required | ||||||
|  |   * r0.6.0 doesn't say they are required, but this has been fixed for the next version of the spec | ||||||
|  | * Updated the type of `r0::sync::sync_events::DeviceLists` fields | ||||||
|  | * Change `r0::device::Device` fields according to the spec | ||||||
|  | 
 | ||||||
|  | Improvements: | ||||||
|  | 
 | ||||||
|  | * `r0::keys::AlgorithmAndDeviceId` now implements `Display` | ||||||
|  | 
 | ||||||
|  | # 0.8.0 | ||||||
|  | 
 | ||||||
|  | Breaking changes: | ||||||
|  | 
 | ||||||
|  | * Update all endpoints to r0.6.0 | ||||||
|  |   * Some of the changes from that might not be listed below, but it should be | ||||||
|  |     easy to figure out what changed from the documentation and compiler errors | ||||||
|  |     if you are using any of the affected endpoints. | ||||||
|  | * Add `server_name` parameter to `r0::join::join_room_by_id_or_alias` | ||||||
|  | * Modify `r0::account::AuthenticationData`: | ||||||
|  |   * Rename to `AuthData` | ||||||
|  |   * Change to an enum to facilitate fallback auth acknowledgements | ||||||
|  |   * Add `auth_parameters` field | ||||||
|  |   * Move to `r0::uiaa` module | ||||||
|  | * Add `room_network` parameter to `r0::directory::get_public_rooms_filtered` to | ||||||
|  |   represent `include_all_networks` and `third_party_instance_id` Matrix fields | ||||||
|  | * Update `r0::account::register` endpoint: | ||||||
|  |   * Remove `bind_email` request field (removed in r0.6.0) | ||||||
|  |   * Remove `inhibit_login` request field, make `access_token` and `device_id` response fields optional (added in r0.4.0) | ||||||
|  |   * Remove deprecated `home_server` response field (removed in r0.4.0) | ||||||
|  | * Update `r0::contact::get_contacts` endpoint to r0.6.0 | ||||||
|  | * Change `UInt` timestamps to `SystemTime` in: | ||||||
|  |   * `media::get_media_preview::Request` | ||||||
|  |   * `push::get_notifications::Notification` | ||||||
|  |   * `server::get_user_info::ConnectionInfo` | ||||||
|  |   * `device::Device` | ||||||
|  | * Change all usages of `HashMap` to `BTreeMap` | ||||||
|  | * Change the messages type that gets sent out using the `r0::client_exchange::send_event_to_device` | ||||||
|  |   request. | ||||||
|  | * Add `M_USER_DEACTIVATED` to `error::ErrorKind` | ||||||
|  | * Make `display_name` field of `r0::membership::joined_events::RoomMember` optional | ||||||
|  | * Update `r0::search::search_events` to r0.6.0 | ||||||
|  | * Add `account_data` field to `r0::sync::sync_events` | ||||||
|  | * Rename `r0::client_exchange` to `r0::to_device` | ||||||
|  | 
 | ||||||
|  | Improvements: | ||||||
|  | 
 | ||||||
|  | * Add types for User-Interactive Authentication API: `r0::uiaa::{AuthFlow, UiaaInfo, UiaaResponse}` | ||||||
|  | * Add missing serde attributes to `get_content_thumbnail` query parameters | ||||||
|  | * Add missing `state` response field to `r0::message::get_message_events` | ||||||
|  | * Normalize `serde_json` imports | ||||||
|  | * Remove dependeny on the `url` crate | ||||||
|  | 
 | ||||||
|  | # 0.7.2 | ||||||
|  | 
 | ||||||
|  | Bug fixes: | ||||||
|  | 
 | ||||||
|  | * Fix `create_room` requests without an `initial_state` field failing deserialization | ||||||
|  | * Fix `sync_events` responses without a `device_one_time_keys_count` field failing deserialization | ||||||
|  | 
 | ||||||
|  | # 0.7.1 | ||||||
|  | 
 | ||||||
|  | Bug fixes: | ||||||
|  | 
 | ||||||
|  | * Fix deserialization of `sync_events::Request` | ||||||
|  | * Fix (de)serialization of `sync_events::RoomSummary` | ||||||
|  | 
 | ||||||
|  | # 0.7.0 | ||||||
|  | 
 | ||||||
|  | Breaking changes: | ||||||
|  | 
 | ||||||
|  | * Update ruma-api to 0.15.0 | ||||||
|  | * Update ruma-events to 0.18.0 | ||||||
|  | * Fix `r0::session::get_login_types` | ||||||
|  | * Add `allow_remote` parameter to `r0::media::get_content` | ||||||
|  | * Add missing parameters for `r0::room::create_room` | ||||||
|  | * Moved `r0::room::create_room::Invite3pid` to `r0::membership::Invite3pid` | ||||||
|  | * Replaced `user_id` parameter of `r0::membership::invite_user` with `recipient` | ||||||
|  |   to allow invitation of users by either Matrix or third party identifiers. | ||||||
|  | * Remove deprecated endpoint `r0::contact::create_contact` (deprecated in r0.6.0) | ||||||
|  | * Add lazy-loading options to `r0::filter::RoomEventFilter` (introduced in r0.5.0) | ||||||
|  | * Change type for `limit` request parameter of `r0::context::get_context` from `u8` to `Option<js_int::UInt>` | ||||||
|  | * Use `std::time::Duration` for appropriate fields on several endpoints: | ||||||
|  |   ``` | ||||||
|  |   r0::{ | ||||||
|  |       account::request_openid_token, | ||||||
|  |       keys::{claim_keys, get_keys}, | ||||||
|  |       presence::get_presence, | ||||||
|  |       sync::sync_events, | ||||||
|  |       typing::create_typing_event, | ||||||
|  |       voip::get_turn_server_info | ||||||
|  |   } | ||||||
|  |   ``` | ||||||
|  | 
 | ||||||
|  | Improvements: | ||||||
|  | 
 | ||||||
|  | * Add an `Error` type that represents the well-known errors in the client-server API | ||||||
|  |   * the response deserialization code will try to create an instance of this type from http responses that indicate an error | ||||||
|  | * Add OpenID token request endpoint. | ||||||
|  | * Add `r0::client_exchange::send_event_to_device` (introduced in r0.3.0) | ||||||
|  | * Add endpoints to retrieve account_data (introduced in r0.5.0) | ||||||
|  | * Add media endpoints: `r0::media::{get_media_config, get_media_preview, get_content_as_filename}` | ||||||
|  | * Add `unstable_features` to `unversioned::get_supported_versions` (introduced in r0.5.0) | ||||||
|  | * Add request and response parameters for `r0::account::deactivate` | ||||||
|  | * Add `r0::session::sso_login` (introduced in r0.5.0) | ||||||
|  | * Add `filter` type for `r0::context::get_context` | ||||||
|  | 
 | ||||||
|  | # 0.6.0 | ||||||
|  | 
 | ||||||
|  | Breaking changes: | ||||||
|  | 
 | ||||||
|  | * Update ruma-api to 0.13.0 | ||||||
|  | * Our Minimum Supported Rust Version is now 1.40.0 | ||||||
|  | * Remove presence list endpoints `r0::presence::{get_subscribed_presences, update_presence_subscriptions}` (removed in r0.5.0) | ||||||
|  | * Refactor `r0::send` endpoints and remove module: | ||||||
|  |   * Move `r0::send::send_message_event` to `r0::message::create_message_event` | ||||||
|  |   * Move `r0::send::send_state_event_for_empty_key` to `r0::state:create_state_event_for_empty_key` | ||||||
|  |   * Move `r0::send::send_state_event_for_key` to `r0::state:create_state_event_for_key` | ||||||
|  | * Refactor `r0::sync` endpoints: | ||||||
|  |   * Move `r0::sync::get_member_events` to `r0::membership::get_member_events` | ||||||
|  |   * Move `r0::sync::get_message_events` to `r0::message::get_message_events` | ||||||
|  |   * Move `r0::sync::get_state_events` to `r0::state::get_state_events` | ||||||
|  |   * Move `r0::sync::get_state_events_for_empty_key` to `r0::state::get_state_events_for_empty_key` | ||||||
|  |   * Move `r0::sync::get_state_events_for_key` to `r0::state::get_state_events_for_key` | ||||||
|  | * Update endpoints for requesting account management tokens via email: | ||||||
|  |   * Move `r0::account::request_password_change_token` to `r0::account::request_password_change_token_via_email` | ||||||
|  |   * Move `r0::account::request_register_token` to `r0::account::request_registration_token_via_email` | ||||||
|  |   * Modify `r0::account::request_registration_token_via_email` not to be rate-limited and require authentication | ||||||
|  | * Merge duplicate enums `r0::contact::get_contact::Medium` and `r0::session::login::Medium` and move them to `r0::thirdparty` | ||||||
|  | 
 | ||||||
|  | Improvements: | ||||||
|  | 
 | ||||||
|  | * Add `r0::device` endpoints | ||||||
|  | * Add `r0::room::get_room_event` (introduced in r0.4.0) | ||||||
|  | * Add `r0::read_marker::set_read_marker` (introduced in r0.4.0) | ||||||
|  | * Add `r0::capabilities::get_capabilities` (introduced in r0.5.0) | ||||||
|  | * Add `r0::keys` endpoints (introduced in r0.3.0) | ||||||
|  | * Add `r0::session::get_login_types` (introduced in r0.4.0) | ||||||
|  | * Add `r0::account::get_username_availability` (introduced in r0.4.0) | ||||||
|  | * Add endpoints to request management tokens (introduced upstream in r0.4.0): | ||||||
|  |   * `r0::account::request_3pid_management_token_via_msisdn` | ||||||
|  |   * `r0::account::request_password_change_token_via_msisdn` | ||||||
|  |   * `r0::account::request_registration_token_via_msisdn` | ||||||
|  |   * `r0::acount::request_3pid_management_token_via_email` | ||||||
|  | * Update `r0::presence_get_presence` from r0.4.0 to r0.6.0 | ||||||
|  | * Add `r0::account::bind_3pid` | ||||||
|  | * Add `r0::account::delete_3pid` | ||||||
|  | * Add `r0::account::unbind_3pid` | ||||||
|  | * Add `r0::push` endpoints | ||||||
|  | * Add `r0::room::upgrade_room` (introduced upstream in r0.5.0) | ||||||
|  | 
 | ||||||
|  | # 0.5.0 | ||||||
|  | 
 | ||||||
|  | Breaking changes: | ||||||
|  | 
 | ||||||
|  | * Our Minimum Supported Rust Version is now 1.39.0 | ||||||
|  | * Update ruma-api from 0.11.0 to 0.12.0 | ||||||
|  | * Move `r0::directory::get_public_rooms::PublicRoomsChunk` to `r0::directory::PublicRoomsChunk` | ||||||
|  | * Move `r0::room::create_room::Visibility` to `r0::room::Visibility` | ||||||
|  | * Move `r0::account::register::AuthenticationData` to `r0::account::AuthenticationData` | ||||||
|  | 
 | ||||||
|  | Improvements: | ||||||
|  | 
 | ||||||
|  | * Update `r0::directory::get_public_rooms` from r0.3.0 to r0.6.0 | ||||||
|  | * Add `r0::directory::get_public_rooms_filtered` (introduced upstream in r0.3.0) | ||||||
|  | * Add `filter` optional parameter to `r0::sync::get_message_events` (introduced upstream in r0.3.0) | ||||||
|  | * Add `r0::appservice::set_room_visibility` (part of application service extensions for the client-server API) | ||||||
|  | * Add `contains_url` to `r0::filter::RoomEventFilter` (introduced upstream in r0.3.0) | ||||||
|  | * Update `r0::account::change_password` from r0.3.0 to r0.6.0 | ||||||
|  |   * Add optional `auth` field | ||||||
							
								
								
									
										203
									
								
								ruma-client-api/CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								ruma-client-api/CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,203 @@ | |||||||
|  | Welcome! Thanks for looking into contributing to our project! | ||||||
|  | 
 | ||||||
|  | # Table of Contents | ||||||
|  | 
 | ||||||
|  | - [Looking for Help?](#looking-for-help) | ||||||
|  |   - [Documentation](#documentation) | ||||||
|  |   - [Chat Rooms](#chat-rooms) | ||||||
|  | - [Reporting Issues](#reporting-issues) | ||||||
|  | - [Submitting Code](#submitting-code) | ||||||
|  |   - [Coding Style](#coding-style) | ||||||
|  |   - [Modifying Endpoints](#modifying-endpoints) | ||||||
|  |   - [Submitting PRs](#submitting-prs) | ||||||
|  |   - [Where do I start?](#where-do-i-start) | ||||||
|  | - [Testing](#testing) | ||||||
|  | - [Contact](#contact) | ||||||
|  | 
 | ||||||
|  | # Looking for Help? | ||||||
|  | 
 | ||||||
|  | Here is a list of helpful resources you can consult: | ||||||
|  | 
 | ||||||
|  | ## Documentation | ||||||
|  | 
 | ||||||
|  | - [Matrix spec Documentation](https://matrix.org/docs/spec/client_server/latest) | ||||||
|  | - Documentation to other Ruma modules: | ||||||
|  |   - [ruma-events](https://docs.rs/ruma-events/) | ||||||
|  |   - [ruma-api](https://docs.rs/ruma-api/) | ||||||
|  |   - [ruma-client](https://docs.rs/ruma-client/) | ||||||
|  | 
 | ||||||
|  | ## Chat Rooms | ||||||
|  | 
 | ||||||
|  | - Ruma Matrix room: [#ruma:matrix.org](https://matrix.to/#/#ruma:matrix.org) | ||||||
|  | - Matrix Developer room: [#matrix-dev:matrix.org](https://matrix.to/#/#matrix-dev:matrix.org) | ||||||
|  | 
 | ||||||
|  | # Reporting Issues | ||||||
|  | 
 | ||||||
|  | If you find any bugs, inconsistencies or other problems, feel free to submit | ||||||
|  | a GitHub [issue](issues). | ||||||
|  | 
 | ||||||
|  | If you have a quick question, it may be easier to leave a message on | ||||||
|  | [#ruma:matrix.org](https://matrix.to/#/#ruma:matrix.org). | ||||||
|  | 
 | ||||||
|  | Also, if you have trouble getting on board, let us know so we can help future | ||||||
|  | contributors to the project overcome that hurdle too. | ||||||
|  | 
 | ||||||
|  | # Submitting Code | ||||||
|  | 
 | ||||||
|  | Ready to write some code? Great! Here are some guidelines to follow to | ||||||
|  | help you on your way: | ||||||
|  | 
 | ||||||
|  | ## Coding Style | ||||||
|  | 
 | ||||||
|  | ### Common types | ||||||
|  | 
 | ||||||
|  | When writing endpoint definitions, use the following mapping from request / | ||||||
|  | response field types listed in the specification to Rust types: | ||||||
|  | 
 | ||||||
|  | Specification type | Rust type | ||||||
|  | -------------------|--------------------------------------------------------------------------------------------------------------------- | ||||||
|  | `boolean`          | `bool` | ||||||
|  | `integer`          | `js_int::UInt` (unless denoted as signed, then `js_int::Int`) | ||||||
|  | `string`           | If for an identifier (e.g. user ID, room ID), use one of the types from `ruma-identifiers`. Otherwise, use `String`. | ||||||
|  | `object`           | `serde_json::Value` | ||||||
|  | `[…]`              | `Vec<…>` | ||||||
|  | `{string: …}`      | `BTreeMap<String, …>` (or `BTreeMap<SomeId, …>`) | ||||||
|  | 
 | ||||||
|  | ### Import Formatting | ||||||
|  | 
 | ||||||
|  | Organize your imports into three groups separated by blank lines: | ||||||
|  | 
 | ||||||
|  | 1. `std` imports | ||||||
|  | 1. External imports (from other crates) | ||||||
|  | 1. Local imports (`self::`, `super::`, `crate::` and things like `LocalType::*`) | ||||||
|  | 
 | ||||||
|  | For example, | ||||||
|  | 
 | ||||||
|  | ```rust | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::MyType; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Also, group imports by module. For example, do this: | ||||||
|  | 
 | ||||||
|  | ```rust | ||||||
|  | use std::{ | ||||||
|  |     collections::BTreeMap, | ||||||
|  |     convert::TryFrom, | ||||||
|  |     fmt::{self, Debug, Display, Formatter}, | ||||||
|  | }; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | as opposed to: | ||||||
|  | 
 | ||||||
|  | ```rust | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | use std::convert::TryFrom; | ||||||
|  | use std::fmt::{self, Debug, Display, Formatter}; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Serde Imports | ||||||
|  | 
 | ||||||
|  | When importing methods and types from `serde_json`, methods should be such as | ||||||
|  | `serde_json::{from,to}_{slice,string,value,vec}` should be imported as | ||||||
|  | `{from,to}_json_{slice,string,value,vec}`. | ||||||
|  | 
 | ||||||
|  | For example: | ||||||
|  | 
 | ||||||
|  | ```rust | ||||||
|  | use serde_json::{ | ||||||
|  |   from_value as from_json_value, | ||||||
|  |   to_str as to_json_str, | ||||||
|  | }; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Also, `serde_json::Value` should be imported as `JsonValue`. | ||||||
|  | 
 | ||||||
|  | ### Code Formatting and Linting | ||||||
|  | 
 | ||||||
|  | Use `rustfmt` to format your code and `clippy` to lint your code. Before | ||||||
|  | committing your changes, go ahead and run `cargo fmt` and `cargo clippy | ||||||
|  | --all-targets --all-features` on the repository to make sure that the | ||||||
|  | formatting and linting checks pass in CI. Note that `clippy` warnings are | ||||||
|  | reported as errors in CI builds, so make sure to handle those before | ||||||
|  | comitting as well. (To install the tools, run `rustup component add rustfmt | ||||||
|  | clippy`.) | ||||||
|  | 
 | ||||||
|  | ### Commit Messages | ||||||
|  | 
 | ||||||
|  | Write commit messages using the imperative mood, as if completing the sentence: | ||||||
|  | "If applied, this commit will \_\_\_." For example, use "Fix some bug" instead | ||||||
|  | of "Fixed some bug" or "Add a feature" instead of "Added a feature". | ||||||
|  | 
 | ||||||
|  | (Take a look at this | ||||||
|  | [blog post](https://www.freecodecamp.org/news/writing-good-commit-messages-a-practical-guide/) | ||||||
|  | for more information on writing good commit messages.) | ||||||
|  | 
 | ||||||
|  | ## Modifying Endpoints | ||||||
|  | 
 | ||||||
|  | ### Matrix Spec Version | ||||||
|  | 
 | ||||||
|  | Use the latest r0.x.x documentation when adding or modifying code. We target | ||||||
|  | the latest minor version of the Matrix specification. (Note: We might | ||||||
|  | reconsider this when the Client-Server API hits r1.0.0.) | ||||||
|  | 
 | ||||||
|  | ### Endpoint Documentation Header | ||||||
|  | 
 | ||||||
|  | Add a comment to the top of each endpoint file that includes the path | ||||||
|  | and a link to the documentation of the spec. You can use the latest | ||||||
|  | version at the time of the commit. For example: | ||||||
|  | 
 | ||||||
|  | ```rust | ||||||
|  | //! [GET /.well-known/matrix/client](https://matrix.org/docs/spec/client_server/r0.4.0#get-well-known-matrix-client) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Naming Endpoints | ||||||
|  | 
 | ||||||
|  | When adding new endpoints, select the module that fits the purpose of the | ||||||
|  | endpoint. When naming the endpoint itself, you can use the following | ||||||
|  | guidelines: | ||||||
|  | - The name should be a verb describing what the client is requesting, e.g. | ||||||
|  |   `get_some_resource`. | ||||||
|  | - Endpoints which are basic CRUD operations should use the prefixes | ||||||
|  |   `create`, `get`, `update`, and `delete`. | ||||||
|  | - The prefix `set` is preferred to create if the resource is a singleton. | ||||||
|  |   In other words, when there's no distinction between `create` and `update`. | ||||||
|  | - Try to use names that are as descriptive as possible and distinct from | ||||||
|  |   other endpoints in all other modules. (For example, instead of | ||||||
|  |   `r0::room::get_event`, use `r0::room::get_room_event`). | ||||||
|  | - If you're not sure what to name it, pick any name and we can help you | ||||||
|  |   with it. | ||||||
|  | 
 | ||||||
|  | ### Tracking Changes | ||||||
|  | 
 | ||||||
|  | Add your changes to the [change log](CHANGELOG.md). If possible, try to | ||||||
|  | find and denote the version of the spec that included the change you are | ||||||
|  | making. | ||||||
|  | 
 | ||||||
|  | ## Submitting PRs | ||||||
|  | 
 | ||||||
|  | Once you're ready to submit your code, create a pull request, and one of our | ||||||
|  | maintainers will review it. Once your PR has passed review, a maintainer will | ||||||
|  | merge the request and you're done! 🎉 | ||||||
|  | 
 | ||||||
|  | ## Where do I start? | ||||||
|  | 
 | ||||||
|  | If this is your first contribution to the project, we recommend taking a look | ||||||
|  | at one of the [open issues][] we've marked for new contributors. | ||||||
|  | 
 | ||||||
|  | It may be helpful to peruse some of the documentation for `ruma-events` and | ||||||
|  | `ruma-api` listed above for some context. | ||||||
|  | 
 | ||||||
|  | [open issues]: https://github.com/ruma/ruma-client-api/issues?q=is%3Aopen+is%3Aissue+label%3Aeffort%2Feasy | ||||||
|  | 
 | ||||||
|  | # Testing | ||||||
|  | 
 | ||||||
|  | Before committing, run `cargo check` to make sure that your changes can build, as well as running the formatting and linting tools [mentioned above](#code-formatting-and-linting). | ||||||
|  | 
 | ||||||
|  | # Contact | ||||||
|  | 
 | ||||||
|  | Thanks again for being a contributor! If you have any questions, join us at | ||||||
|  | [#ruma:matrix.org](https://matrix.to/#/#ruma:matrix.org). | ||||||
							
								
								
									
										33
									
								
								ruma-client-api/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ruma-client-api/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | [package] | ||||||
|  | authors = [ | ||||||
|  |     "Jimmy Cuadra <jimmy@jimmycuadra.com>", | ||||||
|  |     "Jonas Platte <jplatte@posteo.de>", | ||||||
|  |     "Isaiah Inuwa <isaiah.inuwa@gmail.com>", | ||||||
|  | ] | ||||||
|  | categories = ["api-bindings", "web-programming"] | ||||||
|  | description = "Types for the endpoints in the Matrix client-server API." | ||||||
|  | documentation = "https://docs.rs/ruma-client-api" | ||||||
|  | homepage = "https://github.com/ruma/ruma-client-api" | ||||||
|  | keywords = ["matrix", "chat", "messaging", "ruma"] | ||||||
|  | license = "MIT" | ||||||
|  | name = "ruma-client-api" | ||||||
|  | readme = "README.md" | ||||||
|  | repository = "https://github.com/ruma/ruma-client-api" | ||||||
|  | version = "0.9.0" | ||||||
|  | edition = "2018" | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
|  | http = "0.2.1" | ||||||
|  | js_int = { version = "0.1.5", features = ["serde"] } | ||||||
|  | ruma-api = "0.16.1" | ||||||
|  | ruma-common = "0.1.3" | ||||||
|  | ruma-events = { git = "https://github.com/ruma/ruma-events", rev = "c1ee72d" } | ||||||
|  | ruma-identifiers = "0.16.2" | ||||||
|  | ruma-serde = "0.2.2" | ||||||
|  | serde = { version = "1.0.111", features = ["derive"] } | ||||||
|  | serde_json = "1.0.53" | ||||||
|  | strum = { version = "0.18.0", features = ["derive"] } | ||||||
|  | 
 | ||||||
|  | [dev-dependencies] | ||||||
|  | maplit = "1.0.2" | ||||||
|  | matches = "0.1.8" | ||||||
							
								
								
									
										19
									
								
								ruma-client-api/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								ruma-client-api/LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | Copyright (c) 2016 Jimmy Cuadra | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | in the Software without restriction, including without limitation the rights | ||||||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | copies of the Software, and to permit persons to whom the Software is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in | ||||||
|  | all copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | THE SOFTWARE. | ||||||
							
								
								
									
										17
									
								
								ruma-client-api/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								ruma-client-api/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | # ruma-client-api | ||||||
|  | 
 | ||||||
|  | [](https://crates.io/crates/ruma-client-api) | ||||||
|  | [](https://docs.rs/ruma-client-api/) | ||||||
|  | [](https://travis-ci.org/ruma/ruma-client-api) | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **ruma-client-api** contains serializable types for the requests and responses for each endpoint in the [Matrix](https://matrix.org/) client API specification. | ||||||
|  | These types can be shared by client and server code. | ||||||
|  | 
 | ||||||
|  | ## Minimum Rust version | ||||||
|  | 
 | ||||||
|  | ruma-client-api requires Rust 1.40.0 or later. | ||||||
|  | 
 | ||||||
|  | ## Contributing | ||||||
|  | 
 | ||||||
|  | See [CONTRIBUTING.md](CONTRIBUTING.md). | ||||||
							
								
								
									
										245
									
								
								ruma-client-api/src/error.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								ruma-client-api/src/error.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,245 @@ | |||||||
|  | //! Errors that can be sent from the homeserver.
 | ||||||
|  | 
 | ||||||
|  | use std::fmt::{self, Display, Formatter}; | ||||||
|  | 
 | ||||||
|  | use ruma_api::{error::ResponseDeserializationError, EndpointError}; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | use serde_json::{from_slice as from_json_slice, to_vec as to_json_vec}; | ||||||
|  | use strum::{AsRefStr, Display, EnumString}; | ||||||
|  | 
 | ||||||
|  | /// An enum for the error kind. Items may contain additional information.
 | ||||||
|  | #[derive(Debug, Clone, Copy, Serialize, Deserialize, AsRefStr, Display, EnumString)] | ||||||
|  | #[serde(tag = "errcode")] | ||||||
|  | #[cfg_attr(test, derive(PartialEq))] | ||||||
|  | pub enum ErrorKind { | ||||||
|  |     /// M_FORBIDDEN
 | ||||||
|  |     #[serde(rename = "M_FORBIDDEN")] | ||||||
|  |     #[strum(to_string = "M_FORBIDDEN")] | ||||||
|  |     Forbidden, | ||||||
|  | 
 | ||||||
|  |     /// M_UNKNOWN_TOKEN
 | ||||||
|  |     #[serde(rename = "M_UNKNOWN_TOKEN")] | ||||||
|  |     #[strum(to_string = "M_UNKNOWN_TOKEN")] | ||||||
|  |     UnknownToken, | ||||||
|  | 
 | ||||||
|  |     /// M_MISSING_TOKEN
 | ||||||
|  |     #[serde(rename = "M_MISSING_TOKEN")] | ||||||
|  |     #[strum(to_string = "M_MISSING_TOKEN")] | ||||||
|  |     MissingToken, | ||||||
|  | 
 | ||||||
|  |     /// M_BAD_JSON
 | ||||||
|  |     #[serde(rename = "M_BAD_JSON")] | ||||||
|  |     #[strum(to_string = "M_BAD_JSON")] | ||||||
|  |     BadJson, | ||||||
|  | 
 | ||||||
|  |     /// M_NOT_JSON
 | ||||||
|  |     #[serde(rename = "M_NOT_JSON")] | ||||||
|  |     #[strum(to_string = "M_NOT_JSON")] | ||||||
|  |     NotJson, | ||||||
|  | 
 | ||||||
|  |     /// M_NOT_FOUND
 | ||||||
|  |     #[serde(rename = "M_NOT_FOUND")] | ||||||
|  |     #[strum(to_string = "M_NOT_FOUND")] | ||||||
|  |     NotFound, | ||||||
|  | 
 | ||||||
|  |     /// M_LIMIT_EXCEEDED
 | ||||||
|  |     #[serde(rename = "M_LIMIT_EXCEEDED")] | ||||||
|  |     #[strum(to_string = "M_LIMIT_EXCEEDED")] | ||||||
|  |     LimitExceeded, | ||||||
|  | 
 | ||||||
|  |     /// M_UNKNOWN
 | ||||||
|  |     #[serde(rename = "M_UNKNOWN")] | ||||||
|  |     #[strum(to_string = "M_UNKNOWN")] | ||||||
|  |     Unknown, | ||||||
|  | 
 | ||||||
|  |     /// M_UNRECOGNIZED
 | ||||||
|  |     #[serde(rename = "M_UNRECOGNIZED")] | ||||||
|  |     #[strum(to_string = "M_UNRECOGNIZED")] | ||||||
|  |     Unrecognized, | ||||||
|  | 
 | ||||||
|  |     /// M_UNAUTHORIZED
 | ||||||
|  |     #[serde(rename = "M_UNAUTHORIZED")] | ||||||
|  |     #[strum(to_string = "M_UNAUTHORIZED")] | ||||||
|  |     Unauthorized, | ||||||
|  | 
 | ||||||
|  |     /// M_USER_DEACTIVATED
 | ||||||
|  |     #[serde(rename = "M_USER_DEACTIVATED")] | ||||||
|  |     #[strum(to_string = "M_USER_DEACTIVATED")] | ||||||
|  |     UserDeactivated, | ||||||
|  | 
 | ||||||
|  |     /// M_USER_IN_USE
 | ||||||
|  |     #[serde(rename = "M_USER_IN_USE")] | ||||||
|  |     #[strum(to_string = "M_USER_IN_USE")] | ||||||
|  |     UserInUse, | ||||||
|  | 
 | ||||||
|  |     /// M_INVALID_USERNAME
 | ||||||
|  |     #[serde(rename = "M_INVALID_USERNAME")] | ||||||
|  |     #[strum(to_string = "M_INVALID_USERNAME")] | ||||||
|  |     InvalidUsername, | ||||||
|  | 
 | ||||||
|  |     /// M_ROOM_IN_USE
 | ||||||
|  |     #[serde(rename = "M_ROOM_IN_USE")] | ||||||
|  |     #[strum(to_string = "M_ROOM_IN_USE")] | ||||||
|  |     RoomInUse, | ||||||
|  | 
 | ||||||
|  |     /// M_INVALID_ROOM_STATE
 | ||||||
|  |     #[serde(rename = "M_INVALID_ROOM_STATE")] | ||||||
|  |     #[strum(to_string = "M_INVALID_ROOM_STATE")] | ||||||
|  |     InvalidRoomState, | ||||||
|  | 
 | ||||||
|  |     /// M_THREEPID_IN_USE
 | ||||||
|  |     #[serde(rename = "M_THREEPID_IN_USE")] | ||||||
|  |     #[strum(to_string = "M_THREEPID_IN_USE")] | ||||||
|  |     ThreepidInUse, | ||||||
|  | 
 | ||||||
|  |     /// M_THREEPID_NOT_FOUND
 | ||||||
|  |     #[serde(rename = "M_THREEPID_NOT_FOUND")] | ||||||
|  |     #[strum(to_string = "M_THREEPID_NOT_FOUND")] | ||||||
|  |     ThreepidNotFound, | ||||||
|  | 
 | ||||||
|  |     /// M_THREEPID_AUTH_FAILED
 | ||||||
|  |     #[serde(rename = "M_THREEPID_AUTH_FAILED")] | ||||||
|  |     #[strum(to_string = "M_THREEPID_AUTH_FAILED")] | ||||||
|  |     ThreepidAuthFailed, | ||||||
|  | 
 | ||||||
|  |     /// M_THREEPID_DENIED
 | ||||||
|  |     #[serde(rename = "M_THREEPID_DENIED")] | ||||||
|  |     #[strum(to_string = "M_THREEPID_DENIED")] | ||||||
|  |     ThreepidDenied, | ||||||
|  | 
 | ||||||
|  |     /// M_SERVER_NOT_TRUSTED
 | ||||||
|  |     #[serde(rename = "M_SERVER_NOT_TRUSTED")] | ||||||
|  |     #[strum(to_string = "M_SERVER_NOT_TRUSTED")] | ||||||
|  |     ServerNotTrusted, | ||||||
|  | 
 | ||||||
|  |     /// M_UNSUPPORTED_ROOM_VERSION
 | ||||||
|  |     #[serde(rename = "M_UNSUPPORTED_ROOM_VERSION")] | ||||||
|  |     #[strum(to_string = "M_UNSUPPORTED_ROOM_VERSION")] | ||||||
|  |     UnsupportedRoomVersion, | ||||||
|  | 
 | ||||||
|  |     /// M_INCOMPATIBLE_ROOM_VERSION
 | ||||||
|  |     #[serde(rename = "M_INCOMPATIBLE_ROOM_VERSION")] | ||||||
|  |     #[strum(to_string = "M_INCOMPATIBLE_ROOM_VERSION")] | ||||||
|  |     IncompatibleRoomVersion, | ||||||
|  | 
 | ||||||
|  |     /// M_BAD_STATE
 | ||||||
|  |     #[serde(rename = "M_BAD_STATE")] | ||||||
|  |     #[strum(to_string = "M_BAD_STATE")] | ||||||
|  |     BadState, | ||||||
|  | 
 | ||||||
|  |     /// M_GUEST_ACCESS_FORBIDDEN
 | ||||||
|  |     #[serde(rename = "M_GUEST_ACCESS_FORBIDDEN")] | ||||||
|  |     #[strum(to_string = "M_GUEST_ACCESS_FORBIDDEN")] | ||||||
|  |     GuestAccessForbidden, | ||||||
|  | 
 | ||||||
|  |     /// M_CAPTCHA_NEEDED
 | ||||||
|  |     #[serde(rename = "M_CAPTCHA_NEEDED")] | ||||||
|  |     #[strum(to_string = "M_CAPTCHA_NEEDED")] | ||||||
|  |     CaptchaNeeded, | ||||||
|  | 
 | ||||||
|  |     /// M_CAPTCHA_INVALID
 | ||||||
|  |     #[serde(rename = "M_CAPTCHA_INVALID")] | ||||||
|  |     #[strum(to_string = "M_CAPTCHA_INVALID")] | ||||||
|  |     CaptchaInvalid, | ||||||
|  | 
 | ||||||
|  |     /// M_MISSING_PARAM
 | ||||||
|  |     #[serde(rename = "M_MISSING_PARAM")] | ||||||
|  |     #[strum(to_string = "M_MISSING_PARAM")] | ||||||
|  |     MissingParam, | ||||||
|  | 
 | ||||||
|  |     /// M_INVALID_PARAM
 | ||||||
|  |     #[serde(rename = "M_INVALID_PARAM")] | ||||||
|  |     #[strum(to_string = "M_INVALID_PARAM")] | ||||||
|  |     InvalidParam, | ||||||
|  | 
 | ||||||
|  |     /// M_TOO_LARGE
 | ||||||
|  |     #[serde(rename = "M_TOO_LARGE")] | ||||||
|  |     #[strum(to_string = "M_TOO_LARGE")] | ||||||
|  |     TooLarge, | ||||||
|  | 
 | ||||||
|  |     /// M_EXCLUSIVE
 | ||||||
|  |     #[serde(rename = "M_EXCLUSIVE")] | ||||||
|  |     #[strum(to_string = "M_EXCLUSIVE")] | ||||||
|  |     Exclusive, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A Matrix Error without a status code
 | ||||||
|  | #[derive(Debug, Clone, Serialize, Deserialize)] | ||||||
|  | #[cfg_attr(test, derive(PartialEq))] | ||||||
|  | pub struct ErrorBody { | ||||||
|  |     /// A value which can be used to handle an error message
 | ||||||
|  |     #[serde(flatten)] | ||||||
|  |     pub kind: ErrorKind, | ||||||
|  | 
 | ||||||
|  |     /// A human-readable error message, usually a sentence explaining what went wrong.
 | ||||||
|  |     #[serde(rename = "error")] | ||||||
|  |     pub message: String, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A Matrix Error
 | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub struct Error { | ||||||
|  |     /// A value which can be used to handle an error message
 | ||||||
|  |     pub kind: ErrorKind, | ||||||
|  | 
 | ||||||
|  |     /// A human-readable error message, usually a sentence explaining what went wrong.
 | ||||||
|  |     pub message: String, | ||||||
|  | 
 | ||||||
|  |     /// The http status code
 | ||||||
|  |     pub status_code: http::StatusCode, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl EndpointError for Error { | ||||||
|  |     fn try_from_response( | ||||||
|  |         response: http::Response<Vec<u8>>, | ||||||
|  |     ) -> Result<Self, ResponseDeserializationError> { | ||||||
|  |         match from_json_slice::<ErrorBody>(response.body()) { | ||||||
|  |             Ok(error_body) => Ok(error_body.into_error(response.status())), | ||||||
|  |             Err(de_error) => Err(ResponseDeserializationError::new(de_error, response)), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Display for Error { | ||||||
|  |     fn fmt(&self, f: &mut Formatter) -> fmt::Result { | ||||||
|  |         write!( | ||||||
|  |             f, | ||||||
|  |             "[{} / {}] {}", | ||||||
|  |             self.status_code.as_u16(), | ||||||
|  |             self.kind, | ||||||
|  |             self.message | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl std::error::Error for Error {} | ||||||
|  | 
 | ||||||
|  | impl From<Error> for ErrorBody { | ||||||
|  |     fn from(error: Error) -> Self { | ||||||
|  |         Self { | ||||||
|  |             kind: error.kind, | ||||||
|  |             message: error.message, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ErrorBody { | ||||||
|  |     /// Convert the ErrorBody into an Error by adding the http status code.
 | ||||||
|  |     pub fn into_error(self, status_code: http::StatusCode) -> Error { | ||||||
|  |         Error { | ||||||
|  |             kind: self.kind, | ||||||
|  |             message: self.message, | ||||||
|  |             status_code, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<Error> for http::Response<Vec<u8>> { | ||||||
|  |     fn from(error: Error) -> http::Response<Vec<u8>> { | ||||||
|  |         http::Response::builder() | ||||||
|  |             .header(http::header::CONTENT_TYPE, "application/json") | ||||||
|  |             .status(error.status_code) | ||||||
|  |             .body(to_json_vec(&ErrorBody::from(error)).unwrap()) | ||||||
|  |             .unwrap() | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								ruma-client-api/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								ruma-client-api/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | //! Crate ruma_client_api contains serializable types for the requests and responses for each
 | ||||||
|  | //! endpoint in the [Matrix](https://matrix.org/) client API specification. These types can be
 | ||||||
|  | //! shared by client and server code.
 | ||||||
|  | 
 | ||||||
|  | #![deny(
 | ||||||
|  |     missing_copy_implementations, | ||||||
|  |     missing_debug_implementations, | ||||||
|  |     missing_docs | ||||||
|  | )] | ||||||
|  | 
 | ||||||
|  | pub mod error; | ||||||
|  | pub mod r0; | ||||||
|  | pub mod unversioned; | ||||||
|  | 
 | ||||||
|  | pub use error::Error; | ||||||
							
								
								
									
										35
									
								
								ruma-client-api/src/r0.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ruma-client-api/src/r0.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | //! Endpoints for the r0.x.x versions of the client API specification.
 | ||||||
|  | 
 | ||||||
|  | pub mod account; | ||||||
|  | pub mod alias; | ||||||
|  | pub mod appservice; | ||||||
|  | pub mod capabilities; | ||||||
|  | pub mod config; | ||||||
|  | pub mod contact; | ||||||
|  | pub mod context; | ||||||
|  | pub mod device; | ||||||
|  | pub mod directory; | ||||||
|  | pub mod filter; | ||||||
|  | pub mod keys; | ||||||
|  | pub mod media; | ||||||
|  | pub mod membership; | ||||||
|  | pub mod message; | ||||||
|  | pub mod presence; | ||||||
|  | pub mod profile; | ||||||
|  | pub mod push; | ||||||
|  | pub mod read_marker; | ||||||
|  | pub mod receipt; | ||||||
|  | pub mod redact; | ||||||
|  | pub mod room; | ||||||
|  | pub mod search; | ||||||
|  | pub mod server; | ||||||
|  | pub mod session; | ||||||
|  | pub mod state; | ||||||
|  | pub mod sync; | ||||||
|  | pub mod tag; | ||||||
|  | pub mod thirdparty; | ||||||
|  | pub mod to_device; | ||||||
|  | pub mod typing; | ||||||
|  | pub mod uiaa; | ||||||
|  | pub mod user_directory; | ||||||
|  | pub mod voip; | ||||||
							
								
								
									
										43
									
								
								ruma-client-api/src/r0/account.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								ruma-client-api/src/r0/account.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | //! Endpoints for account registration and management.
 | ||||||
|  | 
 | ||||||
|  | pub mod bind_3pid; | ||||||
|  | pub mod change_password; | ||||||
|  | pub mod deactivate; | ||||||
|  | pub mod delete_3pid; | ||||||
|  | pub mod get_username_availability; | ||||||
|  | pub mod register; | ||||||
|  | pub mod request_3pid_management_token_via_email; | ||||||
|  | pub mod request_3pid_management_token_via_msisdn; | ||||||
|  | pub mod request_openid_token; | ||||||
|  | pub mod request_password_change_token_via_email; | ||||||
|  | pub mod request_password_change_token_via_msisdn; | ||||||
|  | pub mod request_registration_token_via_email; | ||||||
|  | pub mod request_registration_token_via_msisdn; | ||||||
|  | pub mod unbind_3pid; | ||||||
|  | 
 | ||||||
|  | pub mod whoami; | ||||||
|  | 
 | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | /// Additional authentication information for requestToken endpoints.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | pub struct IdentityServerInfo { | ||||||
|  |     /// The ID server to send the onward request to as a hostname with an
 | ||||||
|  |     /// appended colon and port number if the port is not the default.
 | ||||||
|  |     pub id_server: String, | ||||||
|  | 
 | ||||||
|  |     /// Access token previously registered with identity server.
 | ||||||
|  |     pub id_access_token: String, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Possible values for deleting or unbinding 3PIDs
 | ||||||
|  | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] | ||||||
|  | #[serde(rename_all = "kebab-case")] | ||||||
|  | pub enum ThirdPartyIdRemovalStatus { | ||||||
|  |     /// Either the homeserver couldn't determine the right identity server to contact, or the
 | ||||||
|  |     /// identity server refused the operation.
 | ||||||
|  |     NoSupport, | ||||||
|  | 
 | ||||||
|  |     /// Success.
 | ||||||
|  |     Success, | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								ruma-client-api/src/r0/account/add_3pid.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ruma-client-api/src/r0/account/add_3pid.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/add](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-add)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use crate::r0::uiaa::{AuthData, UiaaResponse}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Add contact information to a user's account", | ||||||
|  |         method: POST, | ||||||
|  |         name: "add_3pid", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/add", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Additional information for the User-Interactive Authentication API.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub auth: Option<AuthData>, | ||||||
|  | 
 | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: UiaaResponse | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								ruma-client-api/src/r0/account/bind_3pid.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ruma-client-api/src/r0/account/bind_3pid.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/bind](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-bind)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::IdentityServerInfo; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Bind a 3PID to a user's account on an identity server", | ||||||
|  |         method: POST, | ||||||
|  |         name: "bind_3pid", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/bind", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// The ID server to send the onward request to as a hostname with an
 | ||||||
|  |         /// appended colon and port number if the port is not the default.
 | ||||||
|  |         #[serde(flatten)] | ||||||
|  |         pub identity_server_info: IdentityServerInfo, | ||||||
|  | 
 | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								ruma-client-api/src/r0/account/change_password.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								ruma-client-api/src/r0/account/change_password.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/password](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use crate::r0::uiaa::{AuthData, UiaaResponse}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Change the password of the current user's account.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "change_password", | ||||||
|  |         path: "/_matrix/client/r0/account/password", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The new password for the account.
 | ||||||
|  |         pub new_password: String, | ||||||
|  | 
 | ||||||
|  |         /// Additional authentication information for the user-interactive authentication API.
 | ||||||
|  |         pub auth: Option<AuthData>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: UiaaResponse | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								ruma-client-api/src/r0/account/deactivate.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ruma-client-api/src/r0/account/deactivate.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/deactivate](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-deactivate)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use crate::r0::uiaa::{AuthData, UiaaResponse}; | ||||||
|  | 
 | ||||||
|  | use super::ThirdPartyIdRemovalStatus; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Deactivate the current user's account.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "deactivate", | ||||||
|  |         path: "/_matrix/client/r0/account/deactivate", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Additional authentication information for the user-interactive authentication API.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub auth: Option<AuthData>, | ||||||
|  | 
 | ||||||
|  |         /// Identity server from which to unbind the user's third party
 | ||||||
|  |         /// identifier.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub id_server: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Result of unbind operation.
 | ||||||
|  |         pub id_server_unbind_result: ThirdPartyIdRemovalStatus, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: UiaaResponse | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								ruma-client-api/src/r0/account/delete_3pid.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								ruma-client-api/src/r0/account/delete_3pid.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/delete](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-delete)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::ThirdPartyIdRemovalStatus; | ||||||
|  | use crate::r0::thirdparty::Medium; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Delete a 3PID from a user's account on an identity server.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "delete_3pid", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/delete", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Identity server to delete from.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub id_server: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Medium of the 3PID to be removed.
 | ||||||
|  |         pub medium: Medium, | ||||||
|  | 
 | ||||||
|  |         /// Third-party address being removed.
 | ||||||
|  |         pub address: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Result of unbind operation.
 | ||||||
|  |         pub id_server_unbind_result: ThirdPartyIdRemovalStatus, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								ruma-client-api/src/r0/account/get_username_availability.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								ruma-client-api/src/r0/account/get_username_availability.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | //! [GET /_matrix/client/r0/register/available](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-register-available)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Checks to see if a username is available, and valid, for the server.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_username_availability", | ||||||
|  |         path: "/_matrix/client/r0/register/available", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The username to check the availability of.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub username: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A flag to indicate that the username is available.
 | ||||||
|  |         /// This should always be true when the server replies with 200 OK.
 | ||||||
|  |         pub available: bool | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								ruma-client-api/src/r0/account/register.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								ruma-client-api/src/r0/account/register.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | //! [POST /_matrix/client/r0/register](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{DeviceId, UserId}; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | use crate::r0::uiaa::{AuthData, UiaaResponse}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Register an account on this homeserver.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "register", | ||||||
|  |         path: "/_matrix/client/r0/register", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The desired password for the account.
 | ||||||
|  |         ///
 | ||||||
|  |         /// May be empty for accounts that should not be able to log in again
 | ||||||
|  |         /// with a password, e.g., for guest or application service accounts.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub password: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// local part of the desired Matrix ID.
 | ||||||
|  |         ///
 | ||||||
|  |         /// If omitted, the homeserver MUST generate a Matrix ID local part.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub username: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// ID of the client device.
 | ||||||
|  |         ///
 | ||||||
|  |         /// If this does not correspond to a known client device, a new device will be created.
 | ||||||
|  |         /// The server will auto-generate a device_id if this is not specified.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub device_id: Option<DeviceId>, | ||||||
|  | 
 | ||||||
|  |         /// A display name to assign to the newly-created device.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Ignored if `device_id` corresponds to a known device.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub initial_device_display_name: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Additional authentication information for the user-interactive authentication API.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Note that this information is not used to define how the registered user should be
 | ||||||
|  |         /// authenticated, but is instead used to authenticate the register call itself.
 | ||||||
|  |         /// It should be left empty, or omitted, unless an earlier call returned an response
 | ||||||
|  |         /// with status code 401.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub auth: Option<AuthData>, | ||||||
|  | 
 | ||||||
|  |         /// Kind of account to register
 | ||||||
|  |         ///
 | ||||||
|  |         /// Defaults to `User` if omitted.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub kind: Option<RegistrationKind>, | ||||||
|  | 
 | ||||||
|  |         /// If `true`, an `access_token` and `device_id` should not be returned
 | ||||||
|  |         /// from this call, therefore preventing an automatic login.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "ruma_serde::is_default")] | ||||||
|  |         pub inhibit_login: bool, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// An access token for the account.
 | ||||||
|  |         ///
 | ||||||
|  |         /// This access token can then be used to authorize other requests.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub access_token: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The fully-qualified Matrix ID that has been registered.
 | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// ID of the registered device.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Will be the same as the corresponding parameter in the request, if one was specified.
 | ||||||
|  |         pub device_id: Option<DeviceId>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: UiaaResponse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// The kind of account being registered.
 | ||||||
|  | #[derive(Copy, Clone, Debug, Deserialize, Serialize)] | ||||||
|  | #[serde(rename_all = "snake_case")] | ||||||
|  | pub enum RegistrationKind { | ||||||
|  |     /// A guest account
 | ||||||
|  |     ///
 | ||||||
|  |     /// These accounts may have limited permissions and may not be supported by all servers.
 | ||||||
|  |     Guest, | ||||||
|  | 
 | ||||||
|  |     /// A regular user account
 | ||||||
|  |     User, | ||||||
|  | } | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-email-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::IdentityServerInfo; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request a 3PID management token with a 3rd party email.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_3pid_association_token_via_email", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/email/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// The email address.
 | ||||||
|  |         pub email: String, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send the email.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// Return URL for identity server to redirect the client back to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Optional identity server hostname and access token. Deprecated since r0.6.0.
 | ||||||
|  |         #[serde(flatten)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub identity_server_info: Option<IdentityServerInfo>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  | 
 | ||||||
|  |         /// URL to submit validation token to. If omitted, verification happens without client.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub submit_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::IdentityServerInfo; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request a 3PID management token with a phone number.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_3pid_association_token_via_msisdn", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/msisdn/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// Two-letter ISO 3166 country code for the phone number.
 | ||||||
|  |         pub country: String, | ||||||
|  | 
 | ||||||
|  |         /// Phone number to validate.
 | ||||||
|  |         pub phone_number: String, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send the SMS.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// Return URL for identity server to redirect the client back to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Optional identity server hostname and access token. Deprecated since r0.6.0.
 | ||||||
|  |         #[serde(flatten)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub identity_server_info: Option<IdentityServerInfo>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  | 
 | ||||||
|  |         /// URL to submit validation token to. If omitted, verification happens without client.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub submit_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								ruma-client-api/src/r0/account/request_openid_token.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								ruma-client-api/src/r0/account/request_openid_token.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | //! [POST /_matrix/client/r0/user/{userId}/openid/request_token](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-user-userid-openid-request-token)
 | ||||||
|  | 
 | ||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request an OpenID 1.0 token to verify identity with a third party.", | ||||||
|  |         name: "request_openid_token", | ||||||
|  |         method: POST, | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/openid/request_token", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// User ID of authenticated user.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Access token for verifying user's identity.
 | ||||||
|  |         pub access_token: String, | ||||||
|  | 
 | ||||||
|  |         /// Access token type.
 | ||||||
|  |         pub token_type: TokenType, | ||||||
|  | 
 | ||||||
|  |         /// Homeserver domain for verification of user's identity.
 | ||||||
|  |         pub matrix_server_name: String, | ||||||
|  | 
 | ||||||
|  |         /// Seconds until token expiration.
 | ||||||
|  |         #[serde(with = "ruma_serde::duration::secs")] | ||||||
|  |         pub expires_in: Duration, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Access token types.
 | ||||||
|  | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] | ||||||
|  | pub enum TokenType { | ||||||
|  |     /// Bearer token type
 | ||||||
|  |     Bearer, | ||||||
|  | } | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password-email-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::IdentityServerInfo; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request that a password change token is sent to the given email address.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_password_change_token_via_email", | ||||||
|  |         path: "/_matrix/client/r0/account/password/email/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// The email address.
 | ||||||
|  |         pub email: String, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send the email.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// Return URL for identity server to redirect the client back to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Optional identity server hostname and access token. Deprecated since r0.6.0.
 | ||||||
|  |         #[serde(flatten)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub identity_server_info: Option<IdentityServerInfo>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  | 
 | ||||||
|  |         /// URL to submit validation token to. If omitted, verification happens without client.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub submit_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password-msisdn-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request that a password change token is sent to the given phone number.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_password_change_token_via_msisdn", | ||||||
|  |         path: "/_matrix/client/r0/account/password/msisdn/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// Two-letter ISO 3166 country code for the phone number.
 | ||||||
|  |         pub country: String, | ||||||
|  | 
 | ||||||
|  |         /// Phone number to validate.
 | ||||||
|  |         pub phone_number: String, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send the SMS.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// Return URL for identity server to redirect the client back to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  | 
 | ||||||
|  |         /// URL to submit validation token to. If omitted, verification happens without client.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub submit_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | //! [POST /_matrix/client/r0/register/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register-email-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::IdentityServerInfo; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request a registration token with a 3rd party email.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_registration_token_via_email", | ||||||
|  |         path: "/_matrix/client/r0/register/email/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// The email address.
 | ||||||
|  |         pub email: String, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send the email.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// Return URL for identity server to redirect the client back to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Optional identity server hostname and access token. Deprecated since r0.6.0.
 | ||||||
|  |         #[serde(flatten)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub identity_server_info: Option<IdentityServerInfo>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  | 
 | ||||||
|  |         /// URL to submit validation token to. If omitted, verification happens without client.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub submit_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | //! [POST /_matrix/client/r0/register/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register-msisdn-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::IdentityServerInfo; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Request a registration token with a phone number.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_registration_token_via_msisdn", | ||||||
|  |         path: "/_matrix/client/r0/register/msisdn/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// Two-letter ISO 3166 country code for the phone number.
 | ||||||
|  |         pub country: String, | ||||||
|  | 
 | ||||||
|  |         /// Phone number to validate.
 | ||||||
|  |         pub phone_number: String, | ||||||
|  | 
 | ||||||
|  |         /// Return URL for identity server to redirect the client back to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send the SMS.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// Optional identity server hostname and access token. Deprecated since r0.6.0.
 | ||||||
|  |         #[serde(flatten)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub identity_server_info: Option<IdentityServerInfo>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The session identifier given by the identity server.
 | ||||||
|  |         pub sid: String, | ||||||
|  | 
 | ||||||
|  |         /// URL to submit validation token to. If omitted, verification happens without client.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub submit_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								ruma-client-api/src/r0/account/unbind_3pid.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ruma-client-api/src/r0/account/unbind_3pid.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/unbind](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-unbind)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::ThirdPartyIdRemovalStatus; | ||||||
|  | use crate::r0::thirdparty::Medium; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Unbind a 3PID from a user's account on an identity server.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "unbind_3pid", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/unbind", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Identity server to unbind from.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub id_server: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Medium of the 3PID to be removed.
 | ||||||
|  |         pub medium: Medium, | ||||||
|  | 
 | ||||||
|  |         /// Third-party address being removed.
 | ||||||
|  |         pub address: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Result of unbind operation.
 | ||||||
|  |         pub id_server_unbind_result: ThirdPartyIdRemovalStatus, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								ruma-client-api/src/r0/account/whoami.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								ruma-client-api/src/r0/account/whoami.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | //! [GET /_matrix/client/r0/account/whoami](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-account-whoami)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get information about the owner of a given access token.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "whoami", | ||||||
|  |         path: "/_matrix/client/r0/account/whoami", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request {} | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The id of the user that owns the access token.
 | ||||||
|  |         pub user_id: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								ruma-client-api/src/r0/alias.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ruma-client-api/src/r0/alias.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | //! Endpoints for room aliases.
 | ||||||
|  | 
 | ||||||
|  | pub mod create_alias; | ||||||
|  | pub mod delete_alias; | ||||||
|  | pub mod get_alias; | ||||||
							
								
								
									
										28
									
								
								ruma-client-api/src/r0/alias/create_alias.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								ruma-client-api/src/r0/alias/create_alias.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/directory/room/{roomAlias}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-room-roomalias)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomAliasId, RoomId}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Add an alias to a room.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "create_alias", | ||||||
|  |         path: "/_matrix/client/r0/directory/room/:room_alias", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room alias to set.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_alias: RoomAliasId, | ||||||
|  | 
 | ||||||
|  |         /// The room ID to set.
 | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								ruma-client-api/src/r0/alias/delete_alias.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ruma-client-api/src/r0/alias/delete_alias.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | //! [DELETE /_matrix/client/r0/directory/room/{roomAlias}](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-directory-room-roomalias)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomAliasId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Remove an alias from a room.", | ||||||
|  |         method: DELETE, | ||||||
|  |         name: "delete_alias", | ||||||
|  |         path: "/_matrix/client/r0/directory/room/:room_alias", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room alias to remove.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_alias: RoomAliasId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								ruma-client-api/src/r0/alias/get_alias.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								ruma-client-api/src/r0/alias/get_alias.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | //! [GET /_matrix/client/r0/directory/room/{roomAlias}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-directory-room-roomalias)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomAliasId, RoomId}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Resolve a room alias to a room ID.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_alias", | ||||||
|  |         path: "/_matrix/client/r0/directory/room/:room_alias", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room alias.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_alias: RoomAliasId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The room ID for this room alias.
 | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// A list of servers that are aware of this room ID.
 | ||||||
|  |         pub servers: Vec<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								ruma-client-api/src/r0/appservice.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ruma-client-api/src/r0/appservice.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | //! Endpoints part of the application service extension of the client-server API
 | ||||||
|  | 
 | ||||||
|  | pub mod set_room_visibility; | ||||||
							
								
								
									
										34
									
								
								ruma-client-api/src/r0/appservice/set_room_visibility.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ruma-client-api/src/r0/appservice/set_room_visibility.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/directory/list/appservice/{networkId}/{roomId}](https://matrix.org/docs/spec/application_service/r0.1.2#put-matrix-client-r0-directory-list-appservice-networkid-roomid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | use crate::r0::room::Visibility; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Updates the visibility of a given room on the application service's room directory.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "set_room_visibility", | ||||||
|  |         path: "/_matrix/client/r0/directory/list/appservice/:network_id/:room_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The protocol (network) ID to update the room list for.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub network_id: String, | ||||||
|  | 
 | ||||||
|  |         /// The room ID to add to the directory.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// Whether the room should be visible (public) in the directory or not (private).
 | ||||||
|  |         pub visibility: Visibility, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								ruma-client-api/src/r0/capabilities.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ruma-client-api/src/r0/capabilities.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | //! Endpoints for querying the server's supported feature set
 | ||||||
|  | 
 | ||||||
|  | pub mod get_capabilities; | ||||||
							
								
								
									
										73
									
								
								ruma-client-api/src/r0/capabilities/get_capabilities.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								ruma-client-api/src/r0/capabilities/get_capabilities.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | //! [GET /_matrix/client/r0/capabilities](https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-capabilities)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomVersionId; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | use serde_json::Value as JsonValue; | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Gets information about the server's supported feature set and other relevant capabilities.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_capabilities", | ||||||
|  |         path: "/_matrix/client/r0/capabilities", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request {} | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The capabilities the server supports
 | ||||||
|  |         pub capabilities: Capabilities, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Contains information about all the capabilities that the server supports.
 | ||||||
|  | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||||
|  | pub struct Capabilities { | ||||||
|  |     /// Capability to indicate if the user can change their password.
 | ||||||
|  |     #[serde(rename = "m.change_password", skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub change_password: Option<ChangePasswordCapability>, | ||||||
|  | 
 | ||||||
|  |     /// The room versions the server supports.
 | ||||||
|  |     #[serde(rename = "m.room_versions", skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub room_versions: Option<RoomVersionsCapability>, | ||||||
|  | 
 | ||||||
|  |     /// Any other custom capabilities that the server supports outside of the specification,
 | ||||||
|  |     /// labeled using the Java package naming convention and stored as arbitrary JSON values.
 | ||||||
|  |     #[serde(flatten)] | ||||||
|  |     pub custom_capabilities: BTreeMap<String, JsonValue>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Information about the m.change_password capability
 | ||||||
|  | #[derive(Clone, Copy, Debug, Serialize, Deserialize)] | ||||||
|  | pub struct ChangePasswordCapability { | ||||||
|  |     /// True if the user can change their password, false otherwise.
 | ||||||
|  |     pub enabled: bool, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Information about the m.room_versions capability
 | ||||||
|  | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||||
|  | pub struct RoomVersionsCapability { | ||||||
|  |     /// The default room version the server is using for new rooms.
 | ||||||
|  |     pub default: String, | ||||||
|  | 
 | ||||||
|  |     /// A detailed description of the room versions the server supports.
 | ||||||
|  |     pub available: BTreeMap<RoomVersionId, RoomVersionStability>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// The stability of a room version
 | ||||||
|  | #[derive(Clone, Copy, Debug, Serialize, Deserialize)] | ||||||
|  | pub enum RoomVersionStability { | ||||||
|  |     /// Support for the given version is stable.
 | ||||||
|  |     #[serde(rename = "stable")] | ||||||
|  |     Stable, | ||||||
|  | 
 | ||||||
|  |     /// Support for the given version is unstable.
 | ||||||
|  |     #[serde(rename = "unstable")] | ||||||
|  |     Unstable, | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								ruma-client-api/src/r0/config.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ruma-client-api/src/r0/config.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | //! Endpoints for client configuration.
 | ||||||
|  | 
 | ||||||
|  | pub mod get_global_account_data; | ||||||
|  | pub mod get_room_account_data; | ||||||
|  | pub mod set_global_account_data; | ||||||
|  | pub mod set_room_account_data; | ||||||
							
								
								
									
										34
									
								
								ruma-client-api/src/r0/config/get_global_account_data.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ruma-client-api/src/r0/config/get_global_account_data.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | //! [GET /_matrix/client/r0/user/{userId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-user-userid-account-data-type)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::{collections::only, EventJson}; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Gets global account data for a user.", | ||||||
|  |         name: "get_global_account_data", | ||||||
|  |         method: GET, | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/account_data/:event_type", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// User ID of user for whom to retrieve data.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// Type of data to retrieve.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub event_type: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Account data content for the given type.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub account_data: EventJson<only::Event>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								ruma-client-api/src/r0/config/get_room_account_data.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								ruma-client-api/src/r0/config/get_room_account_data.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | //! [GET /_matrix/client/r0/user/{userId}/rooms/{roomId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-user-userid-rooms-roomid-account-data-type)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::{collections::only, EventJson}; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Gets account data room for a user for a given room", | ||||||
|  |         name: "get_room_account_data", | ||||||
|  |         method: GET, | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/account_data/:event_type", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// User ID of user for whom to retrieve data.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// Room ID for which to retrieve data.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// Type of data to retrieve.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub event_type: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Account data content for the given type.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub account_data: EventJson<only::Event>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								ruma-client-api/src/r0/config/set_global_account_data.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								ruma-client-api/src/r0/config/set_global_account_data.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/user/{userId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-user-userid-account-data-type)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | use serde_json::value::RawValue as RawJsonValue; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Sets global account data.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "set_global_account_data", | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/account_data/:event_type", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Arbitrary JSON to store as config data.
 | ||||||
|  |         ///
 | ||||||
|  |         /// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub data: Box<RawJsonValue>, | ||||||
|  | 
 | ||||||
|  |         /// The event type of the account_data to set.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Custom types should be namespaced to avoid clashes.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub event_type: String, | ||||||
|  | 
 | ||||||
|  |         /// The ID of the user to set account_data for.
 | ||||||
|  |         ///
 | ||||||
|  |         /// The access token must be authorized to make requests for this user ID.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								ruma-client-api/src/r0/config/set_room_account_data.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ruma-client-api/src/r0/config/set_room_account_data.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/user/{userId}/rooms/{roomId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-user-userid-rooms-roomid-account-data-type)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | use serde_json::value::RawValue as RawJsonValue; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Associate account data with a room.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "set_room_account_data", | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/account_data/:event_type", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Arbitrary JSON to store as config data.
 | ||||||
|  |         ///
 | ||||||
|  |         /// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub data: Box<RawJsonValue>, | ||||||
|  | 
 | ||||||
|  |         /// The event type of the account_data to set.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Custom types should be namespaced to avoid clashes.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub event_type: String, | ||||||
|  | 
 | ||||||
|  |         /// The ID of the room to set account_data on.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The ID of the user to set account_data for.
 | ||||||
|  |         ///
 | ||||||
|  |         /// The access token must be authorized to make requests for this user ID.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								ruma-client-api/src/r0/contact.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ruma-client-api/src/r0/contact.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | //! Endpoints for account contact information.
 | ||||||
|  | 
 | ||||||
|  | pub mod get_contacts; | ||||||
|  | pub mod request_contact_verification_token; | ||||||
							
								
								
									
										84
									
								
								ruma-client-api/src/r0/contact/get_contacts.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								ruma-client-api/src/r0/contact/get_contacts.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | //! [GET /_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-account-3pid)
 | ||||||
|  | 
 | ||||||
|  | use std::time::SystemTime; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | use crate::r0::thirdparty::Medium; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get a list of 3rd party contacts associated with the user's account.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_contacts", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request {} | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A list of third party identifiers the homeserver has associated with the user's
 | ||||||
|  |         /// account.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |         pub threepids: Vec<ThirdPartyIdentifier>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// An identifier external to Matrix.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | #[cfg_attr(test, derive(PartialEq))] | ||||||
|  | pub struct ThirdPartyIdentifier { | ||||||
|  |     /// The third party identifier address.
 | ||||||
|  |     pub address: String, | ||||||
|  | 
 | ||||||
|  |     /// The medium of third party identifier.
 | ||||||
|  |     pub medium: Medium, | ||||||
|  | 
 | ||||||
|  |     /// The time when the identifier was validated by the identity server.
 | ||||||
|  |     #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] | ||||||
|  |     pub validated_at: SystemTime, | ||||||
|  | 
 | ||||||
|  |     /// The time when the homeserver associated the third party identifier with the user.
 | ||||||
|  |     #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] | ||||||
|  |     pub added_at: SystemTime, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use std::time::{Duration, UNIX_EPOCH}; | ||||||
|  | 
 | ||||||
|  |     use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; | ||||||
|  | 
 | ||||||
|  |     use super::{Medium, ThirdPartyIdentifier}; | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn third_party_identifier_serde() { | ||||||
|  |         let third_party_id = ThirdPartyIdentifier { | ||||||
|  |             address: "monkey@banana.island".into(), | ||||||
|  |             medium: Medium::Email, | ||||||
|  |             validated_at: UNIX_EPOCH + Duration::from_millis(1_535_176_800_000), | ||||||
|  |             added_at: UNIX_EPOCH + Duration::from_millis(1_535_336_848_756), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let third_party_id_serialized = json!({ | ||||||
|  |             "medium": "email", | ||||||
|  |             "address": "monkey@banana.island", | ||||||
|  |             "validated_at": 1_535_176_800_000u64, | ||||||
|  |             "added_at": 1_535_336_848_756u64 | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         assert_eq!( | ||||||
|  |             to_json_value(third_party_id.clone()).unwrap(), | ||||||
|  |             third_party_id_serialized | ||||||
|  |         ); | ||||||
|  |         assert_eq!( | ||||||
|  |             third_party_id, | ||||||
|  |             from_json_value(third_party_id_serialized).unwrap() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | //! [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-email-requesttoken)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Ask for a verification token for a given 3rd party ID.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "request_contact_verification_token", | ||||||
|  |         path: "/_matrix/client/r0/account/3pid/email/requestToken", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Client-generated secret string used to protect this session.
 | ||||||
|  |         pub client_secret: String, | ||||||
|  | 
 | ||||||
|  |         /// The email address.
 | ||||||
|  |         pub email: String, | ||||||
|  | 
 | ||||||
|  |         /// A URL for the identity server to redirect the user to after
 | ||||||
|  |         /// validation is completed.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub next_link: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Used to distinguish protocol level retries from requests to re-send
 | ||||||
|  |         /// the email.
 | ||||||
|  |         pub send_attempt: UInt, | ||||||
|  | 
 | ||||||
|  |         /// The identity server to send the onward request to as a hostname with
 | ||||||
|  |         /// an appended colon and port number if the port is not the default.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub id_server: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// An access token previously registered with the identity server.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Required if an `id_server` is supplied.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub id_access_token: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								ruma-client-api/src/r0/context.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ruma-client-api/src/r0/context.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | //! Endpoints for event context.
 | ||||||
|  | 
 | ||||||
|  | pub mod get_context; | ||||||
							
								
								
									
										84
									
								
								ruma-client-api/src/r0/context/get_context.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								ruma-client-api/src/r0/context/get_context.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | //! [GET /_matrix/client/r0/rooms/{roomId}/context/{eventId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-context-eventid)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::{collections::all, EventJson}; | ||||||
|  | use ruma_identifiers::{EventId, RoomId}; | ||||||
|  | 
 | ||||||
|  | use crate::r0::filter::RoomEventFilter; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get the events immediately preceding and following a given event.", | ||||||
|  |         method: GET, | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/context/:event_id", | ||||||
|  |         name: "get_context", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to get events from.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The event to get context around.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub event_id: EventId, | ||||||
|  | 
 | ||||||
|  |         /// The maximum number of events to return.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Defaults to 10.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(default = "default_limit", skip_serializing_if = "is_default_limit")] | ||||||
|  |         pub limit: UInt, | ||||||
|  | 
 | ||||||
|  |         /// A RoomEventFilter to filter returned events with.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(
 | ||||||
|  |             with = "ruma_serde::json_string", | ||||||
|  |             default, | ||||||
|  |             skip_serializing_if = "Option::is_none" | ||||||
|  |         )] | ||||||
|  |         pub filter: Option<RoomEventFilter>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A token that can be used to paginate backwards with.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub start: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// A token that can be used to paginate forwards with.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub end: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// A list of room events that happened just before the requested event,
 | ||||||
|  |         /// in reverse-chronological order.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |         pub events_before: Vec<EventJson<all::RoomEvent>>, | ||||||
|  | 
 | ||||||
|  |         /// Details of the requested event.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub event: Option<EventJson<all::RoomEvent>>, | ||||||
|  | 
 | ||||||
|  |         /// A list of room events that happened just after the requested event,
 | ||||||
|  |         /// in chronological order.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |         pub events_after: Vec<EventJson<all::RoomEvent>>, | ||||||
|  | 
 | ||||||
|  |         /// The state of the room at the last event returned.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |         pub state: Vec<EventJson<all::StateEvent>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn default_limit() -> UInt { | ||||||
|  |     UInt::from(10u32) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[allow(clippy::trivially_copy_pass_by_ref)] | ||||||
|  | fn is_default_limit(val: &UInt) -> bool { | ||||||
|  |     *val == default_limit() | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								ruma-client-api/src/r0/device.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ruma-client-api/src/r0/device.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | //! Endpoints for managing devices.
 | ||||||
|  | 
 | ||||||
|  | use std::time::SystemTime; | ||||||
|  | 
 | ||||||
|  | use ruma_identifiers::DeviceId; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | pub mod delete_device; | ||||||
|  | pub mod delete_devices; | ||||||
|  | pub mod get_device; | ||||||
|  | pub mod get_devices; | ||||||
|  | pub mod update_device; | ||||||
|  | 
 | ||||||
|  | /// Information about a registered device.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)] | ||||||
|  | pub struct Device { | ||||||
|  |     /// Device ID
 | ||||||
|  |     pub device_id: DeviceId, | ||||||
|  | 
 | ||||||
|  |     /// Public display name of the device.
 | ||||||
|  |     pub display_name: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// Most recently seen IP address of the session.
 | ||||||
|  |     pub last_seen_ip: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// Unix timestamp that the session was last active.
 | ||||||
|  |     #[serde(
 | ||||||
|  |         with = "ruma_serde::time::opt_ms_since_unix_epoch", | ||||||
|  |         default, | ||||||
|  |         skip_serializing_if = "Option::is_none" | ||||||
|  |     )] | ||||||
|  |     pub last_seen_ts: Option<SystemTime>, | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								ruma-client-api/src/r0/device/delete_device.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								ruma-client-api/src/r0/device/delete_device.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | //! [DELETE /_matrix/client/r0/devices/{deviceId}](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-devices-deviceid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::DeviceId; | ||||||
|  | 
 | ||||||
|  | use crate::r0::uiaa::{AuthData, UiaaResponse}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Delete a device for authenticated user.", | ||||||
|  |         method: DELETE, | ||||||
|  |         name: "delete_device", | ||||||
|  |         path: "/_matrix/client/r0/devices/:device_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The device to delete.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub device_id: DeviceId, | ||||||
|  | 
 | ||||||
|  |         /// Additional authentication information for the user-interactive authentication API.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub auth: Option<AuthData>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: UiaaResponse | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								ruma-client-api/src/r0/device/delete_devices.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/src/r0/device/delete_devices.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | //! [POST /_matrix/client/r0/delete_devices](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-delete-devices)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::DeviceId; | ||||||
|  | 
 | ||||||
|  | use crate::r0::uiaa::{AuthData, UiaaResponse}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Delete specified devices.", | ||||||
|  |         method: POST, | ||||||
|  |         path: "/_matrix/client/r0/delete_devices", | ||||||
|  |         name: "delete_devices", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// List of devices to delete.
 | ||||||
|  |         pub devices: Vec<DeviceId>, | ||||||
|  | 
 | ||||||
|  |         /// Additional authentication information for the user-interactive authentication API.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub auth: Option<AuthData>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: UiaaResponse | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								ruma-client-api/src/r0/device/get_device.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/src/r0/device/get_device.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | //! [GET /_matrix/client/r0/devices/{deviceId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-devices-deviceid)
 | ||||||
|  | 
 | ||||||
|  | use super::Device; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::DeviceId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get a device for authenticated user.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_device", | ||||||
|  |         path: "/_matrix/client/r0/devices/:device_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The device to retrieve.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub device_id: DeviceId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Information about the device.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub device: Device, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								ruma-client-api/src/r0/device/get_devices.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ruma-client-api/src/r0/device/get_devices.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | //! [GET /_matrix/client/r0/devices](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-devices)
 | ||||||
|  | 
 | ||||||
|  | use super::Device; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get registered devices for authenticated user.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_devices", | ||||||
|  |         path: "/_matrix/client/r0/devices", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request {} | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A list of all registered devices for this user
 | ||||||
|  |         pub devices: Vec<Device>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								ruma-client-api/src/r0/device/update_device.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/src/r0/device/update_device.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/devices/{deviceId}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-devices-deviceid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::DeviceId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Update metadata for a device.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "update_device", | ||||||
|  |         path: "/_matrix/client/r0/devices/:device_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The device to update.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub device_id: DeviceId, | ||||||
|  | 
 | ||||||
|  |         /// The new display name for this device. If this is `None`, the display name won't be
 | ||||||
|  |         /// changed.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub display_name: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								ruma-client-api/src/r0/directory.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								ruma-client-api/src/r0/directory.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | //! Endpoints for the public room directory.
 | ||||||
|  | 
 | ||||||
|  | pub mod get_public_rooms; | ||||||
|  | pub mod get_public_rooms_filtered; | ||||||
|  | pub mod get_room_visibility; | ||||||
|  | pub mod set_room_visibility; | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_identifiers::{RoomAliasId, RoomId}; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | /// A chunk of a room list response, describing one room
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | pub struct PublicRoomsChunk { | ||||||
|  |     /// Aliases of the room.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub aliases: Vec<RoomAliasId>, | ||||||
|  | 
 | ||||||
|  |     /// The canonical alias of the room, if any.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub canonical_alias: Option<RoomAliasId>, | ||||||
|  | 
 | ||||||
|  |     /// The name of the room, if any.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub name: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// The number of members joined to the room.
 | ||||||
|  |     pub num_joined_members: UInt, | ||||||
|  | 
 | ||||||
|  |     /// The ID of the room.
 | ||||||
|  |     pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |     /// The topic of the room, if any.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub topic: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// Whether the room may be viewed by guest users without joining.
 | ||||||
|  |     pub world_readable: bool, | ||||||
|  | 
 | ||||||
|  |     /// Whether guest users may join the room and participate in it.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If they can, they will be subject to ordinary power level rules like any other user.
 | ||||||
|  |     pub guest_can_join: bool, | ||||||
|  | 
 | ||||||
|  |     /// The URL for the room's avatar, if one is set.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub avatar_url: Option<String>, | ||||||
|  | } | ||||||
							
								
								
									
										52
									
								
								ruma-client-api/src/r0/directory/get_public_rooms.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								ruma-client-api/src/r0/directory/get_public_rooms.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | //! [GET /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-publicrooms)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::PublicRoomsChunk; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get the list of rooms in this homeserver's public directory.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_public_rooms", | ||||||
|  |         path: "/_matrix/client/r0/publicRooms", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Limit for the number of results to return.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub limit: Option<UInt>, | ||||||
|  | 
 | ||||||
|  |         /// Pagination token from a previous request.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub since: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The server to fetch the public room lists from.
 | ||||||
|  |         ///
 | ||||||
|  |         /// `None` means the server this request is sent to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub server: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A paginated chunk of public rooms.
 | ||||||
|  |         pub chunk: Vec<PublicRoomsChunk>, | ||||||
|  | 
 | ||||||
|  |         /// A pagination token for the response.
 | ||||||
|  |         pub next_batch: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// A pagination token that allows fetching previous results.
 | ||||||
|  |         pub prev_batch: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// An estimate on the total number of public rooms, if the server has an estimate.
 | ||||||
|  |         pub total_room_count_estimate: Option<UInt>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										255
									
								
								ruma-client-api/src/r0/directory/get_public_rooms_filtered.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								ruma-client-api/src/r0/directory/get_public_rooms_filtered.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,255 @@ | |||||||
|  | //! [POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-publicrooms)
 | ||||||
|  | 
 | ||||||
|  | use std::fmt; | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use serde::{ | ||||||
|  |     de::{MapAccess, Visitor}, | ||||||
|  |     ser::SerializeStruct, | ||||||
|  |     Deserialize, Deserializer, Serialize, Serializer, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use serde_json::Value as JsonValue; | ||||||
|  | 
 | ||||||
|  | use super::PublicRoomsChunk; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get the list of rooms in this homeserver's public directory.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "get_public_rooms_filtered", | ||||||
|  |         path: "/_matrix/client/r0/publicRooms", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The server to fetch the public room lists from.
 | ||||||
|  |         ///
 | ||||||
|  |         /// `None` means the server this request is sent to.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub server: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Limit for the number of results to return.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub limit: Option<UInt>, | ||||||
|  | 
 | ||||||
|  |         /// Pagination token from a previous request.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub since: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Filter to apply to the results.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub filter: Option<Filter>, | ||||||
|  | 
 | ||||||
|  |         /// Network to fetch the public room lists from.
 | ||||||
|  |         #[serde(flatten, skip_serializing_if = "ruma_serde::is_default")] | ||||||
|  |         pub room_network: RoomNetwork, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A paginated chunk of public rooms.
 | ||||||
|  |         pub chunk: Vec<PublicRoomsChunk>, | ||||||
|  | 
 | ||||||
|  |         /// A pagination token for the response.
 | ||||||
|  |         pub next_batch: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// A pagination token that allows fetching previous results.
 | ||||||
|  |         pub prev_batch: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// An estimate on the total number of public rooms, if the server has an estimate.
 | ||||||
|  |         pub total_room_count_estimate: Option<UInt>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A filter for public rooms lists
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | pub struct Filter { | ||||||
|  |     /// A string to search for in the room metadata, e.g. name, topic, canonical alias etc.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub generic_search_term: Option<String>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Information about which networks/protocols from application services on the
 | ||||||
|  | /// homeserver from which to request rooms.
 | ||||||
|  | #[derive(Clone, Debug, PartialEq, Eq)] | ||||||
|  | pub enum RoomNetwork { | ||||||
|  |     /// Return rooms from the Matrix network.
 | ||||||
|  |     Matrix, | ||||||
|  | 
 | ||||||
|  |     /// Return rooms from all the networks/protocols the homeserver knows about.
 | ||||||
|  |     All, | ||||||
|  | 
 | ||||||
|  |     /// Return rooms from a specific third party network/protocol.
 | ||||||
|  |     ThirdParty(String), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Default for RoomNetwork { | ||||||
|  |     fn default() -> Self { | ||||||
|  |         RoomNetwork::Matrix | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Serialize for RoomNetwork { | ||||||
|  |     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||||
|  |     where | ||||||
|  |         S: Serializer, | ||||||
|  |     { | ||||||
|  |         let mut state; | ||||||
|  |         match self { | ||||||
|  |             Self::Matrix => { | ||||||
|  |                 state = serializer.serialize_struct("RoomNetwork", 0)?; | ||||||
|  |             } | ||||||
|  |             Self::All => { | ||||||
|  |                 state = serializer.serialize_struct("RoomNetwork", 1)?; | ||||||
|  |                 state.serialize_field("include_all_networks", &true)?; | ||||||
|  |             } | ||||||
|  |             Self::ThirdParty(network) => { | ||||||
|  |                 state = serializer.serialize_struct("RoomNetwork", 1)?; | ||||||
|  |                 state.serialize_field("third_party_instance_id", network)?; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         state.end() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'de> Deserialize<'de> for RoomNetwork { | ||||||
|  |     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||||||
|  |     where | ||||||
|  |         D: Deserializer<'de>, | ||||||
|  |     { | ||||||
|  |         deserializer.deserialize_map(RoomNetworkVisitor) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct RoomNetworkVisitor; | ||||||
|  | impl<'de> Visitor<'de> for RoomNetworkVisitor { | ||||||
|  |     type Value = RoomNetwork; | ||||||
|  | 
 | ||||||
|  |     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         formatter.write_str("Network selection") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> | ||||||
|  |     where | ||||||
|  |         M: MapAccess<'de>, | ||||||
|  |     { | ||||||
|  |         let mut include_all_networks = false; | ||||||
|  |         let mut third_party_instance_id = None; | ||||||
|  |         while let Some((key, value)) = access.next_entry::<String, JsonValue>()? { | ||||||
|  |             match key.as_str() { | ||||||
|  |                 "include_all_networks" => { | ||||||
|  |                     include_all_networks = match value.as_bool() { | ||||||
|  |                         Some(b) => b, | ||||||
|  |                         _ => false, | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 "third_party_instance_id" => { | ||||||
|  |                     third_party_instance_id = value.as_str().map(|v| v.to_owned()) | ||||||
|  |                 } | ||||||
|  |                 _ => {} | ||||||
|  |             }; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if include_all_networks { | ||||||
|  |             if third_party_instance_id.is_none() { | ||||||
|  |                 Ok(RoomNetwork::All) | ||||||
|  |             } else { | ||||||
|  |                 Err(M::Error::custom( | ||||||
|  |                     "`include_all_networks = true` and `third_party_instance_id` are mutually exclusive.", | ||||||
|  |                 )) | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             Ok(match third_party_instance_id { | ||||||
|  |                 Some(network) => RoomNetwork::ThirdParty(network), | ||||||
|  |                 None => RoomNetwork::Matrix, | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; | ||||||
|  | 
 | ||||||
|  |     use super::RoomNetwork; | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_matrix_network_only() { | ||||||
|  |         let json = json!({}); | ||||||
|  |         assert_eq!(to_json_value(RoomNetwork::Matrix).unwrap(), json); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserialize_matrix_network_only() { | ||||||
|  |         let json = json!({ "include_all_networks": false }); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<RoomNetwork>(json).unwrap(), | ||||||
|  |             RoomNetwork::Matrix | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_default_network_is_empty() { | ||||||
|  |         let json = json!({}); | ||||||
|  |         assert_eq!(to_json_value(RoomNetwork::default()).unwrap(), json); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserialize_empty_network_is_default() { | ||||||
|  |         let json = json!({}); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<RoomNetwork>(json).unwrap(), | ||||||
|  |             RoomNetwork::default() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_include_all_networks() { | ||||||
|  |         let json = json!({ "include_all_networks": true }); | ||||||
|  |         assert_eq!(to_json_value(RoomNetwork::All).unwrap(), json); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserialize_include_all_networks() { | ||||||
|  |         let json = json!({ "include_all_networks": true }); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<RoomNetwork>(json).unwrap(), | ||||||
|  |             RoomNetwork::All | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_third_party_network() { | ||||||
|  |         let json = json!({ "third_party_instance_id": "freenode" }); | ||||||
|  |         assert_eq!( | ||||||
|  |             to_json_value(RoomNetwork::ThirdParty("freenode".to_string())).unwrap(), | ||||||
|  |             json | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserialize_third_party_network() { | ||||||
|  |         let json = json!({ "third_party_instance_id": "freenode" }); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<RoomNetwork>(json).unwrap(), | ||||||
|  |             RoomNetwork::ThirdParty("freenode".to_string()) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserialize_include_all_networks_and_third_party_exclusivity() { | ||||||
|  |         let json = json!({ "include_all_networks": true, "third_party_instance_id": "freenode" }); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<RoomNetwork>(json) | ||||||
|  |                 .unwrap_err() | ||||||
|  |                 .to_string() | ||||||
|  |                 .as_str(), | ||||||
|  |             "`include_all_networks = true` and `third_party_instance_id` are mutually exclusive." | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								ruma-client-api/src/r0/directory/get_room_visibility.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/src/r0/directory/get_room_visibility.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | //! [GET /_matrix/client/r0/directory/list/room/{roomId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-directory-list-room-roomid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | use crate::r0::room::Visibility; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get the visibility of a public room on a directory.", | ||||||
|  |         name: "get_room_visibility", | ||||||
|  |         method: GET, | ||||||
|  |         path: "/_matrix/client/r0/directory/list/room/:room_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The ID of the room of which to request the visibility.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Visibility of the room.
 | ||||||
|  |         pub visibility: Visibility, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								ruma-client-api/src/r0/directory/set_room_visibility.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/src/r0/directory/set_room_visibility.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/directory/list/room/{roomId}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-list-room-roomid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | use crate::r0::room::Visibility; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Set the visibility of a public room on a directory.", | ||||||
|  |         name: "set_room_visibility", | ||||||
|  |         method: PUT, | ||||||
|  |         path: "/_matrix/client/r0/directory/list/room/:room_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The ID of the room of which to set the visibility.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// New visibility setting for the room.
 | ||||||
|  |         pub visibility: Visibility, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										381
									
								
								ruma-client-api/src/r0/filter.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										381
									
								
								ruma-client-api/src/r0/filter.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,381 @@ | |||||||
|  | //! Endpoints for event filters.
 | ||||||
|  | 
 | ||||||
|  | pub mod create_filter; | ||||||
|  | pub mod get_filter; | ||||||
|  | 
 | ||||||
|  | use std::fmt; | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | use serde::{ | ||||||
|  |     de::{MapAccess, Visitor}, | ||||||
|  |     ser::SerializeStruct, | ||||||
|  |     Deserialize, Deserializer, Serialize, Serializer, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// Format to use for returned events
 | ||||||
|  | #[derive(Copy, Clone, Debug, Deserialize, Serialize)] | ||||||
|  | #[serde(rename_all = "snake_case")] | ||||||
|  | pub enum EventFormat { | ||||||
|  |     /// Client format, as described in the Client API.
 | ||||||
|  |     Client, | ||||||
|  | 
 | ||||||
|  |     /// Raw events from federation.
 | ||||||
|  |     Federation, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Filters to be applied to room events
 | ||||||
|  | #[derive(Clone, Debug, Default, Deserialize, Serialize)] | ||||||
|  | pub struct RoomEventFilter { | ||||||
|  |     /// A list of event types to exclude.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then no event types are excluded. A matching type will be excluded
 | ||||||
|  |     /// even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any
 | ||||||
|  |     /// sequence of characters.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub not_types: Vec<String>, | ||||||
|  | 
 | ||||||
|  |     /// A list of room IDs to exclude.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then no rooms are excluded. A matching room will be excluded even if
 | ||||||
|  |     /// it is listed in the 'rooms' filter.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub not_rooms: Vec<String>, | ||||||
|  | 
 | ||||||
|  |     /// The maximum number of events to return.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub limit: Option<UInt>, | ||||||
|  | 
 | ||||||
|  |     /// A list of room IDs to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all rooms are included.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub rooms: Option<Vec<RoomId>>, | ||||||
|  | 
 | ||||||
|  |     /// A list of sender IDs to exclude.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then no senders are excluded. A matching sender will be excluded even
 | ||||||
|  |     /// if it is listed in the 'senders' filter.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub not_senders: Vec<UserId>, | ||||||
|  | 
 | ||||||
|  |     /// A list of senders IDs to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all senders are included.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub senders: Option<Vec<UserId>>, | ||||||
|  | 
 | ||||||
|  |     /// A list of event types to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all event types are included. A '*' can be used as a wildcard to
 | ||||||
|  |     /// match any sequence of characters.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub types: Option<Vec<String>>, | ||||||
|  | 
 | ||||||
|  |     /// If `true` include only events with a URL key in their content.
 | ||||||
|  |     /// If `false`, exclude such events.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this item is absent then all event types are included.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub contains_url: Option<bool>, | ||||||
|  | 
 | ||||||
|  |     /// Options to control lazy-loading of membership events.
 | ||||||
|  |     #[serde(flatten)] | ||||||
|  |     pub lazy_load_options: LazyLoadOptions, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl RoomEventFilter { | ||||||
|  |     /// A filter that can be used to ignore all room events
 | ||||||
|  |     pub fn ignore_all() -> Self { | ||||||
|  |         Self { | ||||||
|  |             types: Some(vec![]), | ||||||
|  |             ..Default::default() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Filters to be applied to room data
 | ||||||
|  | #[derive(Clone, Debug, Default, Deserialize, Serialize)] | ||||||
|  | pub struct RoomFilter { | ||||||
|  |     /// Include rooms that the user has left in the sync.
 | ||||||
|  |     ///
 | ||||||
|  |     /// Defaults to false if not included.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub include_leave: Option<bool>, | ||||||
|  | 
 | ||||||
|  |     /// The per user account data to include for rooms.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub account_data: Option<RoomEventFilter>, | ||||||
|  | 
 | ||||||
|  |     /// The message and state update events to include for rooms.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub timeline: Option<RoomEventFilter>, | ||||||
|  | 
 | ||||||
|  |     /// The events that aren't recorded in the room history, e.g. typing and receipts, to include
 | ||||||
|  |     /// for rooms.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub ephemeral: Option<RoomEventFilter>, | ||||||
|  | 
 | ||||||
|  |     /// The state events to include for rooms.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub state: Option<RoomEventFilter>, | ||||||
|  | 
 | ||||||
|  |     /// A list of room IDs to exclude.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then no rooms are excluded. A matching room will be excluded even if
 | ||||||
|  |     /// it is listed in the 'rooms' filter. This filter is applied before the filters in
 | ||||||
|  |     /// `ephemeral`, `state`, `timeline` or `account_data`.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub not_rooms: Vec<RoomId>, | ||||||
|  | 
 | ||||||
|  |     /// A list of room IDs to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all rooms are included. This filter is applied before the
 | ||||||
|  |     /// filters in `ephemeral`, `state`, `timeline` or `account_data`.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub rooms: Option<Vec<RoomId>>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl RoomFilter { | ||||||
|  |     /// A filter that can be used to ignore all room events (of any type)
 | ||||||
|  |     pub fn ignore_all() -> Self { | ||||||
|  |         Self { | ||||||
|  |             rooms: Some(vec![]), | ||||||
|  |             ..Default::default() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Filter for not-room data
 | ||||||
|  | #[derive(Clone, Debug, Default, Deserialize, Serialize)] | ||||||
|  | pub struct Filter { | ||||||
|  |     /// A list of event types to exclude.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then no event types are excluded. A matching type will be excluded
 | ||||||
|  |     /// even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any
 | ||||||
|  |     /// sequence of characters.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub not_types: Vec<String>, | ||||||
|  | 
 | ||||||
|  |     /// The maximum number of events to return.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub limit: Option<UInt>, | ||||||
|  | 
 | ||||||
|  |     /// A list of senders IDs to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all senders are included.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub senders: Option<Vec<UserId>>, | ||||||
|  | 
 | ||||||
|  |     /// A list of event types to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all event types are included. A '*' can be used as a wildcard to
 | ||||||
|  |     /// match any sequence of characters.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub types: Option<Vec<String>>, | ||||||
|  | 
 | ||||||
|  |     /// A list of sender IDs to exclude.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then no senders are excluded. A matching sender will be excluded even
 | ||||||
|  |     /// if it is listed in the 'senders' filter.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |     pub not_senders: Vec<UserId>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Filter { | ||||||
|  |     /// A filter that can be used to ignore all events
 | ||||||
|  |     pub fn ignore_all() -> Self { | ||||||
|  |         Self { | ||||||
|  |             types: Some(vec![]), | ||||||
|  |             ..Default::default() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A filter definition
 | ||||||
|  | #[derive(Clone, Debug, Default, Deserialize, Serialize)] | ||||||
|  | pub struct FilterDefinition { | ||||||
|  |     /// List of event fields to include.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this list is absent then all fields are included. The entries may include '.' charaters
 | ||||||
|  |     /// to indicate sub-fields. So ['content.body'] will include the 'body' field of the 'content'
 | ||||||
|  |     /// object. A literal '.' character in a field name may be escaped using a '\'. A server may
 | ||||||
|  |     /// include more fields than were requested.
 | ||||||
|  |     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub event_fields: Option<Vec<String>>, | ||||||
|  | 
 | ||||||
|  |     /// The format to use for events.
 | ||||||
|  |     ///
 | ||||||
|  |     /// 'client' will return the events in a format suitable for clients. 'federation' will return
 | ||||||
|  |     /// the raw event as received over federation. The default is 'client'.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub event_format: Option<EventFormat>, | ||||||
|  | 
 | ||||||
|  |     /// The presence updates to include.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub presence: Option<Filter>, | ||||||
|  | 
 | ||||||
|  |     /// The user account data that isn't associated with rooms to include.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub account_data: Option<Filter>, | ||||||
|  | 
 | ||||||
|  |     /// Filters to be applied to room data.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub room: Option<RoomFilter>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl FilterDefinition { | ||||||
|  |     /// A filter that can be used to ignore all events
 | ||||||
|  |     pub fn ignore_all() -> Self { | ||||||
|  |         Self { | ||||||
|  |             account_data: Some(Filter::ignore_all()), | ||||||
|  |             room: Some(RoomFilter::ignore_all()), | ||||||
|  |             presence: Some(Filter::ignore_all()), | ||||||
|  |             ..Default::default() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Specifies options for [lazy-loading membership events][lazy-loading] on
 | ||||||
|  | /// supported endpoints
 | ||||||
|  | ///
 | ||||||
|  | /// [lazy-loading]: https://matrix.org/docs/spec/client_server/r0.6.0#lazy-loading-room-members
 | ||||||
|  | #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||||||
|  | pub enum LazyLoadOptions { | ||||||
|  |     /// Disables lazy-loading of membership events.
 | ||||||
|  |     Disabled, | ||||||
|  | 
 | ||||||
|  |     /// Enables lazy-loading of events.
 | ||||||
|  |     Enabled { | ||||||
|  |         /// If `true`, sends all membership events for all events, even if they have
 | ||||||
|  |         /// already been sent to the client. Defaults to `false`.
 | ||||||
|  |         include_redundant_members: bool, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Serialize for LazyLoadOptions { | ||||||
|  |     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||||
|  |     where | ||||||
|  |         S: Serializer, | ||||||
|  |     { | ||||||
|  |         let mut state; | ||||||
|  |         match *self { | ||||||
|  |             Self::Enabled { | ||||||
|  |                 include_redundant_members: true, | ||||||
|  |             } => { | ||||||
|  |                 state = serializer.serialize_struct("LazyLoad", 2)?; | ||||||
|  |                 state.serialize_field("lazy_load_members", &true)?; | ||||||
|  |                 state.serialize_field("include_redundant_members", &true)?; | ||||||
|  |             } | ||||||
|  |             Self::Enabled { .. } => { | ||||||
|  |                 state = serializer.serialize_struct("LazyLoad", 1)?; | ||||||
|  |                 state.serialize_field("lazy_load_members", &true)?; | ||||||
|  |             } | ||||||
|  |             _ => { | ||||||
|  |                 state = serializer.serialize_struct("LazyLoad", 0)?; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         state.end() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Default for LazyLoadOptions { | ||||||
|  |     fn default() -> Self { | ||||||
|  |         Self::Disabled | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct LazyLoadOptionsVisitor; | ||||||
|  | 
 | ||||||
|  | impl<'de> Visitor<'de> for LazyLoadOptionsVisitor { | ||||||
|  |     type Value = LazyLoadOptions; | ||||||
|  | 
 | ||||||
|  |     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         formatter.write_str("Lazy load options") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> | ||||||
|  |     where | ||||||
|  |         M: MapAccess<'de>, | ||||||
|  |     { | ||||||
|  |         let mut lazy_load_members = false; | ||||||
|  |         let mut include_redundant_members = false; | ||||||
|  |         while let Some((key, value)) = access.next_entry::<String, bool>()? { | ||||||
|  |             match &*key { | ||||||
|  |                 "lazy_load_members" => lazy_load_members = value, | ||||||
|  |                 "include_redundant_members" => include_redundant_members = value, | ||||||
|  |                 _ => {} | ||||||
|  |             }; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(if lazy_load_members { | ||||||
|  |             LazyLoadOptions::Enabled { | ||||||
|  |                 include_redundant_members, | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             LazyLoadOptions::Disabled | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'de> Deserialize<'de> for LazyLoadOptions { | ||||||
|  |     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||||||
|  |     where | ||||||
|  |         D: Deserializer<'de>, | ||||||
|  |     { | ||||||
|  |         deserializer.deserialize_map(LazyLoadOptionsVisitor) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; | ||||||
|  | 
 | ||||||
|  |     use super::LazyLoadOptions; | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serializing_disabled_lazy_load() { | ||||||
|  |         let lazy_load_options = LazyLoadOptions::Disabled; | ||||||
|  |         assert_eq!(to_json_value(lazy_load_options).unwrap(), json!({})); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serializing_lazy_load_no_redundant() { | ||||||
|  |         let lazy_load_options = LazyLoadOptions::Enabled { | ||||||
|  |             include_redundant_members: false, | ||||||
|  |         }; | ||||||
|  |         assert_eq!( | ||||||
|  |             to_json_value(lazy_load_options).unwrap(), | ||||||
|  |             json!({ "lazy_load_members": true }) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serializing_lazy_load_with_redundant() { | ||||||
|  |         let lazy_load_options = LazyLoadOptions::Enabled { | ||||||
|  |             include_redundant_members: true, | ||||||
|  |         }; | ||||||
|  |         assert_eq!( | ||||||
|  |             to_json_value(lazy_load_options).unwrap(), | ||||||
|  |             json!({ "lazy_load_members": true, "include_redundant_members": true }) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserializing_no_lazy_load() { | ||||||
|  |         let json = json!({}); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<LazyLoadOptions>(json).unwrap(), | ||||||
|  |             LazyLoadOptions::Disabled, | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_deserializing_ignore_redundant_members_when_no_lazy_load() { | ||||||
|  |         let json = json!({ "include_redundant_members": true }); | ||||||
|  |         assert_eq!( | ||||||
|  |             from_json_value::<LazyLoadOptions>(json).unwrap(), | ||||||
|  |             LazyLoadOptions::Disabled, | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								ruma-client-api/src/r0/filter/create_filter.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ruma-client-api/src/r0/filter/create_filter.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | //! [POST /_matrix/client/r0/user/{userId}/filter](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-user-userid-filter)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | use super::FilterDefinition; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Create a new filter for event retrieval.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "create_filter", | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/filter", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The ID of the user uploading the filter.
 | ||||||
|  |         ///
 | ||||||
|  |         /// The access token must be authorized to make requests for this user ID.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The filter definition.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub filter: FilterDefinition, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The ID of the filter that was created.
 | ||||||
|  |         pub filter_id: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								ruma-client-api/src/r0/filter/get_filter.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ruma-client-api/src/r0/filter/get_filter.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | //! [GET /_matrix/client/r0/user/{userId}/filter/{filterId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-user-userid-filter-filterid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | use super::FilterDefinition; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Retrieve a previously created filter.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_filter", | ||||||
|  |         path: "/_matrix/client/r0/user/:user_id/filter/:filter_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user ID to download a filter for.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The ID of the filter to download.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub filter_id: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The filter definition.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub filter: FilterDefinition, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										164
									
								
								ruma-client-api/src/r0/keys.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								ruma-client-api/src/r0/keys.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,164 @@ | |||||||
|  | //! Endpoints for key management
 | ||||||
|  | 
 | ||||||
|  | use std::{ | ||||||
|  |     collections::BTreeMap, | ||||||
|  |     convert::TryFrom, | ||||||
|  |     fmt::{self, Debug, Display, Formatter}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use ruma_events::Algorithm; | ||||||
|  | use ruma_identifiers::{DeviceId, UserId}; | ||||||
|  | use serde::{ | ||||||
|  |     de::{self, Unexpected}, | ||||||
|  |     Deserialize, Deserializer, Serialize, Serializer, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pub mod claim_keys; | ||||||
|  | pub mod get_key_changes; | ||||||
|  | pub mod get_keys; | ||||||
|  | pub mod upload_keys; | ||||||
|  | 
 | ||||||
|  | /// The basic key algorithms in the specification
 | ||||||
|  | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] | ||||||
|  | pub enum KeyAlgorithm { | ||||||
|  |     /// The Ed25519 signature algorithm.
 | ||||||
|  |     #[serde(rename = "ed25519")] | ||||||
|  |     Ed25519, | ||||||
|  | 
 | ||||||
|  |     /// The Curve25519 ECDH algorithm.
 | ||||||
|  |     #[serde(rename = "curve25519")] | ||||||
|  |     Curve25519, | ||||||
|  | 
 | ||||||
|  |     /// The Curve25519 ECDH algorithm, but the key also contains signatures
 | ||||||
|  |     #[serde(rename = "signed_curve25519")] | ||||||
|  |     SignedCurve25519, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Display for KeyAlgorithm { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { | ||||||
|  |         let algorithm_str = match *self { | ||||||
|  |             KeyAlgorithm::Ed25519 => "ed25519", | ||||||
|  |             KeyAlgorithm::Curve25519 => "curve25519", | ||||||
|  |             KeyAlgorithm::SignedCurve25519 => "signed_curve25519", | ||||||
|  |         }; | ||||||
|  |         write!(f, "{}", algorithm_str)?; | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TryFrom<&'_ str> for KeyAlgorithm { | ||||||
|  |     type Error = &'static str; | ||||||
|  |     fn try_from(s: &str) -> Result<Self, Self::Error> { | ||||||
|  |         match s { | ||||||
|  |             "ed25519" => Ok(KeyAlgorithm::Ed25519), | ||||||
|  |             "curve25519" => Ok(KeyAlgorithm::Curve25519), | ||||||
|  |             "signed_curve25519" => Ok(KeyAlgorithm::SignedCurve25519), | ||||||
|  |             _ => Err("Unknown algorithm"), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A key algorithm and a device id, combined with a ':'
 | ||||||
|  | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||||||
|  | pub struct AlgorithmAndDeviceId(pub KeyAlgorithm, pub DeviceId); | ||||||
|  | 
 | ||||||
|  | impl Display for AlgorithmAndDeviceId { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { | ||||||
|  |         write!(f, "{}:{}", self.0, self.1) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Serialize for AlgorithmAndDeviceId { | ||||||
|  |     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||||
|  |     where | ||||||
|  |         S: Serializer, | ||||||
|  |     { | ||||||
|  |         serializer.serialize_str(&self.to_string()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'de> Deserialize<'de> for AlgorithmAndDeviceId { | ||||||
|  |     #[allow(clippy::comparison_chain)] | ||||||
|  |     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||||||
|  |     where | ||||||
|  |         D: Deserializer<'de>, | ||||||
|  |     { | ||||||
|  |         let value = String::deserialize(deserializer)?; | ||||||
|  |         let parts = value.split(':').collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|  |         const EXPECTED: &str = "a string composed of an algorithm and a device id separated by ':'"; | ||||||
|  | 
 | ||||||
|  |         if parts.len() < 2 { | ||||||
|  |             return Err(de::Error::invalid_type( | ||||||
|  |                 Unexpected::Other("string without a ':' separator"), | ||||||
|  |                 &EXPECTED, | ||||||
|  |             )); | ||||||
|  |         } else if parts.len() > 2 { | ||||||
|  |             return Err(de::Error::invalid_type( | ||||||
|  |                 Unexpected::Other("string with more than one ':' separator"), | ||||||
|  |                 &EXPECTED, | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let algorithm_result = KeyAlgorithm::try_from(parts[0]); | ||||||
|  |         match algorithm_result { | ||||||
|  |             Ok(algorithm) => Ok(AlgorithmAndDeviceId(algorithm, parts[1].to_string())), | ||||||
|  |             Err(_) => Err(de::Error::invalid_value( | ||||||
|  |                 Unexpected::Str(parts[0]), | ||||||
|  |                 &"valid key algorithm", | ||||||
|  |             )), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Identity keys for a device.
 | ||||||
|  | #[derive(Debug, Clone, Serialize, Deserialize)] | ||||||
|  | pub struct DeviceKeys { | ||||||
|  |     /// The ID of the user the device belongs to. Must match the user ID used when logging in.
 | ||||||
|  |     pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |     /// The ID of the device these keys belong to. Must match the device ID used when logging in.
 | ||||||
|  |     pub device_id: DeviceId, | ||||||
|  | 
 | ||||||
|  |     /// The encryption algorithms supported by this device.
 | ||||||
|  |     pub algorithms: Vec<Algorithm>, | ||||||
|  | 
 | ||||||
|  |     /// Public identity keys.
 | ||||||
|  |     pub keys: BTreeMap<AlgorithmAndDeviceId, String>, | ||||||
|  | 
 | ||||||
|  |     /// Signatures for the device key object.
 | ||||||
|  |     pub signatures: BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>, | ||||||
|  | 
 | ||||||
|  |     /// Additional data added to the device key information by intermediate servers, and
 | ||||||
|  |     /// not covered by the signatures.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub unsigned: Option<UnsignedDeviceInfo>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Additional data added to device key information by intermediate servers.
 | ||||||
|  | #[derive(Debug, Clone, Serialize, Deserialize)] | ||||||
|  | pub struct UnsignedDeviceInfo { | ||||||
|  |     /// The display name which the user set on the device.
 | ||||||
|  |     pub device_display_name: Option<String>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A key for the SignedCurve25519 algorithm
 | ||||||
|  | #[derive(Debug, Clone, Serialize, Deserialize)] | ||||||
|  | pub struct SignedKey { | ||||||
|  |     /// Base64-encoded 32-byte Curve25519 public key.
 | ||||||
|  |     pub key: String, | ||||||
|  | 
 | ||||||
|  |     /// Signatures for the key object.
 | ||||||
|  |     pub signatures: BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A one-time public key for "pre-key" messages.
 | ||||||
|  | #[derive(Debug, Clone, Serialize, Deserialize)] | ||||||
|  | #[serde(untagged)] | ||||||
|  | pub enum OneTimeKey { | ||||||
|  |     /// A key containing signatures, for the SignedCurve25519 algorithm.
 | ||||||
|  |     SignedKey(SignedKey), | ||||||
|  | 
 | ||||||
|  |     /// A string-valued key, for the Ed25519 and Curve25519 algorithms.
 | ||||||
|  |     Key(String), | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								ruma-client-api/src/r0/keys/claim_keys.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								ruma-client-api/src/r0/keys/claim_keys.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | //! [POST /_matrix/client/r0/keys/claim](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-keys-claim)
 | ||||||
|  | 
 | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | 
 | ||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{DeviceId, UserId}; | ||||||
|  | use serde_json::Value as JsonValue; | ||||||
|  | 
 | ||||||
|  | use super::{AlgorithmAndDeviceId, KeyAlgorithm, OneTimeKey}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Claims one-time keys for use in pre-key messages.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "claim_keys", | ||||||
|  |         path: "/_matrix/client/r0/keys/claim", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The time (in milliseconds) to wait when downloading keys from remote servers.
 | ||||||
|  |         /// 10 seconds is the recommended default.
 | ||||||
|  |         #[serde(
 | ||||||
|  |             with = "ruma_serde::duration::opt_ms", | ||||||
|  |             default, | ||||||
|  |             skip_serializing_if = "Option::is_none", | ||||||
|  |         )] | ||||||
|  |         pub timeout: Option<Duration>, | ||||||
|  | 
 | ||||||
|  |         /// The keys to be claimed.
 | ||||||
|  |         pub one_time_keys: BTreeMap<UserId, BTreeMap<DeviceId, KeyAlgorithm>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// If any remote homeservers could not be reached, they are recorded here.
 | ||||||
|  |         /// The names of the properties are the names of the unreachable servers.
 | ||||||
|  |         pub failures: BTreeMap<String, JsonValue>, | ||||||
|  | 
 | ||||||
|  |         /// One-time keys for the queried devices.
 | ||||||
|  |         pub one_time_keys: BTreeMap<UserId, BTreeMap<DeviceId, BTreeMap<AlgorithmAndDeviceId, OneTimeKey>>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								ruma-client-api/src/r0/keys/get_key_changes.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								ruma-client-api/src/r0/keys/get_key_changes.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | //! [GET /_matrix/client/r0/keys/changes](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-keys-changes)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Gets a list of users who have updated their device identity keys since a previous sync token.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_key_changes", | ||||||
|  |         path: "/_matrix/client/r0/keys/changes", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The desired start point of the list.
 | ||||||
|  |         /// Should be the next_batch field from a response to an earlier call to /sync.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub from: String, | ||||||
|  | 
 | ||||||
|  |         /// The desired end point of the list.
 | ||||||
|  |         /// Should be the next_batch field from a recent call to /sync - typically the most recent such call.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub to: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The Matrix User IDs of all users who updated their device identity keys.
 | ||||||
|  |         pub changed: Vec<UserId>, | ||||||
|  | 
 | ||||||
|  |         /// The Matrix User IDs of all users who may have left all the end-to-end
 | ||||||
|  |         /// encrypted rooms they previously shared with the user.
 | ||||||
|  |         pub left: Vec<UserId> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										55
									
								
								ruma-client-api/src/r0/keys/get_keys.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ruma-client-api/src/r0/keys/get_keys.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | //! [POST /_matrix/client/r0/keys/query](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-keys-query)
 | ||||||
|  | 
 | ||||||
|  | use std::{collections::BTreeMap, time::Duration}; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{DeviceId, UserId}; | ||||||
|  | use serde_json::Value as JsonValue; | ||||||
|  | 
 | ||||||
|  | use super::DeviceKeys; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Returns the current devices and identity keys for the given users.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "get_keys", | ||||||
|  |         path: "/_matrix/client/r0/keys/query", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The time (in milliseconds) to wait when downloading keys from remote
 | ||||||
|  |         /// servers. 10 seconds is the recommended default.
 | ||||||
|  |         #[serde(
 | ||||||
|  |             with = "ruma_serde::duration::opt_ms", | ||||||
|  |             default, | ||||||
|  |             skip_serializing_if = "Option::is_none", | ||||||
|  |         )] | ||||||
|  |         pub timeout: Option<Duration>, | ||||||
|  | 
 | ||||||
|  |         /// The keys to be downloaded. An empty list indicates all devices for
 | ||||||
|  |         /// the corresponding user.
 | ||||||
|  |         pub device_keys: BTreeMap<UserId, Vec<DeviceId>>, | ||||||
|  | 
 | ||||||
|  |         /// If the client is fetching keys as a result of a device update
 | ||||||
|  |         /// received in a sync request, this should be the 'since' token of that
 | ||||||
|  |         /// sync request, or any later sync token. This allows the server to
 | ||||||
|  |         /// ensure its response contains the keys advertised by the notification
 | ||||||
|  |         /// in that sync.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub token: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// If any remote homeservers could not be reached, they are recorded
 | ||||||
|  |         /// here. The names of the properties are the names of the unreachable
 | ||||||
|  |         /// servers.
 | ||||||
|  |         pub failures: BTreeMap<String, JsonValue>, | ||||||
|  | 
 | ||||||
|  |         /// Information on the queried devices.
 | ||||||
|  |         pub device_keys: BTreeMap<UserId, BTreeMap<DeviceId, DeviceKeys>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								ruma-client-api/src/r0/keys/upload_keys.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								ruma-client-api/src/r0/keys/upload_keys.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | //! [POST /_matrix/client/r0/keys/upload](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-keys-upload)
 | ||||||
|  | 
 | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm, OneTimeKey}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Publishes end-to-end encryption keys for the device.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "upload_keys", | ||||||
|  |         path: "/_matrix/client/r0/keys/upload", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Identity keys for the device. May be absent if no new identity keys are required.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub device_keys: Option<DeviceKeys>, | ||||||
|  | 
 | ||||||
|  |         /// One-time public keys for "pre-key" messages.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub one_time_keys: Option<BTreeMap<AlgorithmAndDeviceId, OneTimeKey>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// For each key algorithm, the number of unclaimed one-time keys of that
 | ||||||
|  |         /// type currently held on the server for this device.
 | ||||||
|  |         pub one_time_key_counts: BTreeMap<KeyAlgorithm, UInt> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								ruma-client-api/src/r0/media.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ruma-client-api/src/r0/media.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | //! Endpoints for the media repository.
 | ||||||
|  | 
 | ||||||
|  | pub mod create_content; | ||||||
|  | pub mod get_content; | ||||||
|  | pub mod get_content_as_filename; | ||||||
|  | pub mod get_content_thumbnail; | ||||||
|  | pub mod get_media_config; | ||||||
|  | pub mod get_media_preview; | ||||||
							
								
								
									
										37
									
								
								ruma-client-api/src/r0/media/create_content.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								ruma-client-api/src/r0/media/create_content.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | //! [POST /_matrix/media/r0/upload](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-media-r0-upload)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Upload content to the media store.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "create_media_content", | ||||||
|  |         path: "/_matrix/media/r0/upload", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The name of the file being uploaded.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub filename: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The content type of the file being uploaded.
 | ||||||
|  |         // TODO: This should be optional.
 | ||||||
|  |         #[ruma_api(header = CONTENT_TYPE)] | ||||||
|  |         pub content_type: String, | ||||||
|  | 
 | ||||||
|  |         /// The file contents to upload.
 | ||||||
|  |         #[ruma_api(raw_body)] | ||||||
|  |         pub file: Vec<u8>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The MXC URI for the uploaded content.
 | ||||||
|  |         pub content_uri: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								ruma-client-api/src/r0/media/get_content.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								ruma-client-api/src/r0/media/get_content.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | //! [GET /_matrix/media/r0/download/{serverName}/{mediaId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-download-servername-mediaid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Retrieve content from the media store.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_media_content", | ||||||
|  |         path: "/_matrix/media/r0/download/:server_name/:media_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The media ID from the mxc:// URI (the path component).
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub media_id: String, | ||||||
|  | 
 | ||||||
|  |         /// The server name from the mxc:// URI (the authoritory component).
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub server_name: String, | ||||||
|  | 
 | ||||||
|  |         /// Whether to fetch media deemed remote.
 | ||||||
|  |         /// Used to prevent routing loops. Defaults to `true`.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub allow_remote: Option<bool>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The content that was previously uploaded.
 | ||||||
|  |         #[ruma_api(raw_body)] | ||||||
|  |         pub file: Vec<u8>, | ||||||
|  | 
 | ||||||
|  |         /// The content type of the file that was previously uploaded.
 | ||||||
|  |         #[ruma_api(header = CONTENT_TYPE)] | ||||||
|  |         pub content_type: String, | ||||||
|  | 
 | ||||||
|  |         /// The name of the file that was previously uploaded, if set.
 | ||||||
|  |         #[ruma_api(header = CONTENT_DISPOSITION)] | ||||||
|  |         pub content_disposition: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										49
									
								
								ruma-client-api/src/r0/media/get_content_as_filename.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								ruma-client-api/src/r0/media/get_content_as_filename.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | //! [GET /_matrix/media/r0/download/{serverName}/{mediaId}/{fileName}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-download-servername-mediaid-filename)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Retrieve content from the media store, specifying a filename to return.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_media_content_as_filename", | ||||||
|  |         path: "/_matrix/media/r0/download/:server_name/:media_id/:filename", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The media ID from the mxc:// URI (the path component).
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub media_id: String, | ||||||
|  | 
 | ||||||
|  |         /// The server name from the mxc:// URI (the authoritory component).
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub server_name: String, | ||||||
|  | 
 | ||||||
|  |         /// The filename to return in the `Content-Disposition` header.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub filename: String, | ||||||
|  | 
 | ||||||
|  |         /// Whether to fetch media deemed remote.
 | ||||||
|  |         /// Used to prevent routing loops. Defaults to `true`.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub allow_remote: Option<bool>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The content that was previously uploaded.
 | ||||||
|  |         #[ruma_api(raw_body)] | ||||||
|  |         pub file: Vec<u8>, | ||||||
|  | 
 | ||||||
|  |         /// The content type of the file that was previously uploaded.
 | ||||||
|  |         #[ruma_api(header = CONTENT_TYPE)] | ||||||
|  |         pub content_type: String, | ||||||
|  | 
 | ||||||
|  |         /// The name of the file that was previously uploaded, if set.
 | ||||||
|  |         #[ruma_api(header = CONTENT_DISPOSITION)] | ||||||
|  |         pub content_disposition: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								ruma-client-api/src/r0/media/get_content_thumbnail.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								ruma-client-api/src/r0/media/get_content_thumbnail.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | //! [GET /_matrix/media/r0/thumbnail/{serverName}/{mediaId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-thumbnail-servername-mediaid)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | /// The desired resizing method.
 | ||||||
|  | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] | ||||||
|  | #[serde(rename_all = "snake_case")] | ||||||
|  | pub enum Method { | ||||||
|  |     /// Crop the original to produce the requested image dimensions.
 | ||||||
|  |     Crop, | ||||||
|  | 
 | ||||||
|  |     /// Maintain the original aspect ratio of the source image.
 | ||||||
|  |     Scale, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get a thumbnail of content from the media store.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_content_thumbnail", | ||||||
|  |         path: "/_matrix/media/r0/thumbnail/:server_name/:media_id", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// Whether to fetch media deemed remote.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Used to prevent routing loops. Defaults to `true`.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub allow_remote: Option<bool>, | ||||||
|  | 
 | ||||||
|  |         /// The media ID from the mxc:// URI (the path component).
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub media_id: String, | ||||||
|  | 
 | ||||||
|  |         /// The server name from the mxc:// URI (the authoritory component).
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub server_name: String, | ||||||
|  | 
 | ||||||
|  |         /// The *desired* height of the thumbnail. The actual thumbnail may not match the size
 | ||||||
|  |         /// specified.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub height: UInt, | ||||||
|  | 
 | ||||||
|  |         /// The desired resizing method.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub method: Option<Method>, | ||||||
|  | 
 | ||||||
|  |         /// The *desired* width of the thumbnail. The actual thumbnail may not match the size
 | ||||||
|  |         /// specified.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub width: UInt, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The content type of the thumbnail.
 | ||||||
|  |         #[ruma_api(header = CONTENT_TYPE)] | ||||||
|  |         pub content_type: String, | ||||||
|  | 
 | ||||||
|  |         /// A thumbnail of the requested content.
 | ||||||
|  |         #[ruma_api(raw_body)] | ||||||
|  |         pub file: Vec<u8>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								ruma-client-api/src/r0/media/get_media_config.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ruma-client-api/src/r0/media/get_media_config.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | //! [GET /_matrix/media/r0/config](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-config)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Gets the config for the media repository.", | ||||||
|  |         method: GET, | ||||||
|  |         path: "/_matrix/media/r0/config", | ||||||
|  |         name: "get_media_config", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request {} | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// Maximum size of upload in bytes.
 | ||||||
|  |         #[serde(rename = "m.upload.size")] | ||||||
|  |         pub upload_size: UInt, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								ruma-client-api/src/r0/media/get_media_preview.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								ruma-client-api/src/r0/media/get_media_preview.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | //! [GET /_matrix/media/r0/preview_url](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-preview-url)
 | ||||||
|  | 
 | ||||||
|  | use std::time::SystemTime; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use serde_json::value::RawValue as RawJsonValue; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get a preview for a URL.", | ||||||
|  |         name: "get_media_preview", | ||||||
|  |         method: GET, | ||||||
|  |         path: "/_matrix/media/r0/preview_url", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// URL to get a preview of.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub url: String, | ||||||
|  | 
 | ||||||
|  |         /// Preferred point in time (in milliseconds) to return a preview for.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] | ||||||
|  |         pub ts: SystemTime, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// OpenGraph-like data for the URL.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Differences from OpenGraph: the image size in bytes is added to the `matrix:image:size`
 | ||||||
|  |         /// field, and `og:image` returns the MXC URI to the image, if any.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub data: Option<Box<RawJsonValue>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use serde_json::{ | ||||||
|  |         from_value as from_json_value, json, | ||||||
|  |         value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue}, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // Since BTreeMap<String, Box<RawJsonValue>> deserialization doesn't seem to
 | ||||||
|  |     // work, test that Option<RawJsonValue> works
 | ||||||
|  |     #[test] | ||||||
|  |     fn raw_json_deserialize() { | ||||||
|  |         type OptRawJson = Option<Box<RawJsonValue>>; | ||||||
|  | 
 | ||||||
|  |         assert!(from_json_value::<OptRawJson>(json!(null)) | ||||||
|  |             .unwrap() | ||||||
|  |             .is_none()); | ||||||
|  |         assert!(from_json_value::<OptRawJson>(json!("test")) | ||||||
|  |             .unwrap() | ||||||
|  |             .is_some()); | ||||||
|  |         assert!(from_json_value::<OptRawJson>(json!({ "a": "b" })) | ||||||
|  |             .unwrap() | ||||||
|  |             .is_some()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // For completeness sake, make sure serialization works too
 | ||||||
|  |     #[test] | ||||||
|  |     fn raw_json_serialize() { | ||||||
|  |         assert!(to_raw_json_value(&json!(null)).is_ok()); | ||||||
|  |         assert!(to_raw_json_value(&json!("string")).is_ok()); | ||||||
|  |         assert!(to_raw_json_value(&json!({})).is_ok()); | ||||||
|  |         assert!(to_raw_json_value(&json!({ "a": "b" })).is_ok()); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										52
									
								
								ruma-client-api/src/r0/membership.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								ruma-client-api/src/r0/membership.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | //! Endpoints for room membership.
 | ||||||
|  | 
 | ||||||
|  | pub mod ban_user; | ||||||
|  | pub mod forget_room; | ||||||
|  | pub mod get_member_events; | ||||||
|  | pub mod invite_user; | ||||||
|  | pub mod join_room_by_id; | ||||||
|  | pub mod join_room_by_id_or_alias; | ||||||
|  | pub mod joined_members; | ||||||
|  | pub mod joined_rooms; | ||||||
|  | pub mod kick_user; | ||||||
|  | pub mod leave_room; | ||||||
|  | pub mod unban_user; | ||||||
|  | 
 | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | 
 | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | use crate::r0::thirdparty::Medium; | ||||||
|  | 
 | ||||||
|  | /// A signature of an `m.third_party_invite` token to prove that this user owns a third party
 | ||||||
|  | /// identity which has been invited to the room.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | pub struct ThirdPartySigned { | ||||||
|  |     /// The Matrix ID of the user who issued the invite.
 | ||||||
|  |     pub sender: String, | ||||||
|  | 
 | ||||||
|  |     /// The Matrix ID of the invitee.
 | ||||||
|  |     pub mxid: String, | ||||||
|  | 
 | ||||||
|  |     /// The state key of the m.third_party_invite event.
 | ||||||
|  |     pub token: String, | ||||||
|  | 
 | ||||||
|  |     /// A signatures object containing a signature of the entire signed object.
 | ||||||
|  |     pub signatures: BTreeMap<String, BTreeMap<String, String>>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Represents third party IDs to invite to the room.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] | ||||||
|  | pub struct Invite3pid { | ||||||
|  |     /// Hostname and port of identity server to be used for account lookups.
 | ||||||
|  |     pub id_server: String, | ||||||
|  | 
 | ||||||
|  |     /// An access token registered with the identity server.
 | ||||||
|  |     pub id_access_token: String, | ||||||
|  | 
 | ||||||
|  |     /// Type of third party ID.
 | ||||||
|  |     pub medium: Medium, | ||||||
|  | 
 | ||||||
|  |     /// Third party identifier.
 | ||||||
|  |     pub address: String, | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								ruma-client-api/src/r0/membership/ban_user.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ruma-client-api/src/r0/membership/ban_user.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/ban](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-ban)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Ban a user from a room.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "ban_user", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/ban", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to kick the user from.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The user to ban.
 | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The reason for banning the user.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub reason: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								ruma-client-api/src/r0/membership/forget_room.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ruma-client-api/src/r0/membership/forget_room.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/forget](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-forget)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Forget a room.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "forget_room", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/forget", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to forget.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								ruma-client-api/src/r0/membership/get_member_events.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								ruma-client-api/src/r0/membership/get_member_events.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | //! [GET /_matrix/client/r0/rooms/{roomId}/members](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-members)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::{room::member::MemberEvent, EventJson}; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get membership events for a room.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_member_events", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/members", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to get the member events for.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The point in time (pagination token) to return members for in the room. This token can
 | ||||||
|  |         /// be obtained from a prev_batch token returned for each room by the sync API.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub at: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The kind of memberships to filter for. Defaults to no filtering if unspecified. When
 | ||||||
|  |         /// specified alongside not_membership, the two parameters create an 'or' condition: either
 | ||||||
|  |         /// the membership is the same as membership or is not the same as not_membership.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub membership: Option<MembershipEventFilter>, | ||||||
|  | 
 | ||||||
|  |         /// The kind of memberships to *exclude* from the results. Defaults to no filtering if
 | ||||||
|  |         /// unspecified.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub not_membership: Option<MembershipEventFilter>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A list of member events.
 | ||||||
|  |         pub chunk: Vec<EventJson<MemberEvent>> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// The kind of membership events to filter for.
 | ||||||
|  | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] | ||||||
|  | #[serde(rename_all = "lowercase")] | ||||||
|  | pub enum MembershipEventFilter { | ||||||
|  |     /// The user has joined.
 | ||||||
|  |     Join, | ||||||
|  | 
 | ||||||
|  |     /// The user has been invited.
 | ||||||
|  |     Invite, | ||||||
|  | 
 | ||||||
|  |     /// The user has left.
 | ||||||
|  |     Leave, | ||||||
|  | 
 | ||||||
|  |     /// The user has been banned.
 | ||||||
|  |     Ban, | ||||||
|  | } | ||||||
							
								
								
									
										90
									
								
								ruma-client-api/src/r0/membership/invite_user.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								ruma-client-api/src/r0/membership/invite_user.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/invite][invite-by-user-id]
 | ||||||
|  | //!
 | ||||||
|  | //! This endpoint has two forms: one to invite a user
 | ||||||
|  | //! [by their Matrix identifier][invite-by-user-id], and one to invite a user
 | ||||||
|  | //! [by their third party identifier][invite-by-3pid].
 | ||||||
|  | //!
 | ||||||
|  | //! [invite-by-user-id]: https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-invite
 | ||||||
|  | //! [invite-by-3pid]: https://matrix.org/docs/spec/client_server/r0.6.0#id101
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | use super::Invite3pid; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Invite a user to a room.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "invite_user", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/invite", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room where the user should be invited.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The user to invite.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub recipient: InvitationRecipient, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Distinguishes between invititations by Matrix or third party identifiers.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] | ||||||
|  | #[serde(untagged)] | ||||||
|  | pub enum InvitationRecipient { | ||||||
|  |     /// Used to invite user by their Matrix identifer.
 | ||||||
|  |     UserId { | ||||||
|  |         /// Matrix identifier of user.
 | ||||||
|  |         user_id: UserId, | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /// Used to invite user by a third party identifer.
 | ||||||
|  |     ThirdPartyId(Invite3pid), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use std::convert::TryFrom; | ||||||
|  | 
 | ||||||
|  |     use ruma_identifiers::UserId; | ||||||
|  |     use serde_json::{from_value as from_json_value, json}; | ||||||
|  | 
 | ||||||
|  |     use super::InvitationRecipient; | ||||||
|  |     use crate::r0::{membership::Invite3pid, thirdparty::Medium}; | ||||||
|  |     #[test] | ||||||
|  |     fn deserialize_invite_by_user_id() { | ||||||
|  |         let incoming = | ||||||
|  |             from_json_value::<InvitationRecipient>(json!({ "user_id": "@carl:example.org" })) | ||||||
|  |                 .unwrap(); | ||||||
|  |         let user_id = UserId::try_from("@carl:example.org").unwrap(); | ||||||
|  |         let recipient = InvitationRecipient::UserId { user_id }; | ||||||
|  |         assert_eq!(incoming, recipient); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn deserialize_invite_by_3pid() { | ||||||
|  |         let incoming = from_json_value::<InvitationRecipient>(json!({ | ||||||
|  |             "id_server": "example.org", | ||||||
|  |             "id_access_token": "abcdefghijklmnop", | ||||||
|  |             "medium": "email", | ||||||
|  |             "address": "carl@example.org" | ||||||
|  |         })) | ||||||
|  |         .unwrap(); | ||||||
|  |         let recipient = InvitationRecipient::ThirdPartyId(Invite3pid { | ||||||
|  |             id_server: "example.org".to_string(), | ||||||
|  |             id_access_token: "abcdefghijklmnop".to_string(), | ||||||
|  |             medium: Medium::Email, | ||||||
|  |             address: "carl@example.org".to_string(), | ||||||
|  |         }); | ||||||
|  |         assert_eq!(incoming, recipient); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								ruma-client-api/src/r0/membership/join_room_by_id.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ruma-client-api/src/r0/membership/join_room_by_id.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/join](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-join)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | use super::ThirdPartySigned; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Join a room using its ID.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "join_room_by_id", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/join", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room where the user should be invited.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The signature of a `m.third_party_invite` token to prove that this user owns a third
 | ||||||
|  |         /// party identity which has been invited to the room.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub third_party_signed: Option<ThirdPartySigned>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The room that the user joined.
 | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
| @ -0,0 +1,41 @@ | |||||||
|  | //! [POST /_matrix/client/r0/join/{roomIdOrAlias}](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-join-roomidoralias)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, RoomIdOrAliasId}; | ||||||
|  | 
 | ||||||
|  | use super::ThirdPartySigned; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Join a room using its ID or one of its aliases.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "join_room_by_id_or_alias", | ||||||
|  |         path: "/_matrix/client/r0/join/:room_id_or_alias", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room where the user should be invited.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id_or_alias: RoomIdOrAliasId, | ||||||
|  | 
 | ||||||
|  |         /// The servers to attempt to join the room through. One of the servers
 | ||||||
|  |         /// must be participating in the room.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(default)] | ||||||
|  |         pub server_name: Vec<String>, | ||||||
|  | 
 | ||||||
|  |         /// The signature of a `m.third_party_invite` token to prove that this user owns a third
 | ||||||
|  |         /// party identity which has been invited to the room.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub third_party_signed: Option<ThirdPartySigned>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The room that the user joined.
 | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								ruma-client-api/src/r0/membership/joined_members.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ruma-client-api/src/r0/membership/joined_members.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | //! [GET /_matrix/client/r0/rooms/{roomId}/joined_members](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-joined-members)
 | ||||||
|  | 
 | ||||||
|  | use std::collections::BTreeMap; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get a map of user ids to member info objects for members of the room. Primarily for use in Application Services.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "joined_members", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/joined_members", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to get the members of.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A list of the rooms the user is in, i.e.
 | ||||||
|  |         /// the ID of each room in which the user has joined membership.
 | ||||||
|  |         pub joined: BTreeMap<UserId, RoomMember>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Information about a room member.
 | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | pub struct RoomMember { | ||||||
|  |     /// The display name of the user.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub display_name: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// The mxc avatar url of the user.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub avatar_url: Option<String>, | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								ruma-client-api/src/r0/membership/joined_rooms.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ruma-client-api/src/r0/membership/joined_rooms.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | //! [GET /_matrix/client/r0/joined_rooms](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-joined-rooms)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get a list of the user's current rooms.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "joined_rooms", | ||||||
|  |         path: "/_matrix/client/r0/joined_rooms", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request {} | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A list of the rooms the user is in, i.e. the ID of each room in
 | ||||||
|  |         /// which the user has joined membership.
 | ||||||
|  |         pub joined_rooms: Vec<RoomId>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								ruma-client-api/src/r0/membership/kick_user.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ruma-client-api/src/r0/membership/kick_user.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/kick](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-kick)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Kick a user from a room.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "kick_user", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/kick", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to kick the user from.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The user to kick.
 | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The reason for kicking the user.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub reason: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								ruma-client-api/src/r0/membership/leave_room.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ruma-client-api/src/r0/membership/leave_room.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/leave](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-leave)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Leave a room.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "leave_room", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/leave", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to leave.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								ruma-client-api/src/r0/membership/unban_user.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								ruma-client-api/src/r0/membership/unban_user.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | //! [POST /_matrix/client/r0/rooms/{roomId}/unban](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-unban)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::{RoomId, UserId}; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Unban a user from a room.", | ||||||
|  |         method: POST, | ||||||
|  |         name: "unban_user", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/unban", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to unban the user from.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The user to unban.
 | ||||||
|  |         pub user_id: UserId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								ruma-client-api/src/r0/message.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ruma-client-api/src/r0/message.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | //! Enpoints for sending and receiving messages
 | ||||||
|  | 
 | ||||||
|  | pub mod create_message_event; | ||||||
|  | pub mod get_message_events; | ||||||
							
								
								
									
										50
									
								
								ruma-client-api/src/r0/message/create_message_event.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								ruma-client-api/src/r0/message/create_message_event.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::EventType; | ||||||
|  | use ruma_identifiers::{EventId, RoomId}; | ||||||
|  | use serde_json::value::RawValue as RawJsonValue; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Send a message event to a room.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "create_message_event", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/send/:event_type/:txn_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to send the event to.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The type of event to send.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub event_type: EventType, | ||||||
|  | 
 | ||||||
|  |         /// The transaction ID for this event.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Clients should generate an ID unique across requests with the
 | ||||||
|  |         /// same access token; it will be used by the server to ensure
 | ||||||
|  |         /// idempotency of requests.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub txn_id: String, | ||||||
|  | 
 | ||||||
|  |         /// The event's content. The type for this field will be updated in a
 | ||||||
|  |         /// future release, until then you can create a value using
 | ||||||
|  |         /// `serde_json::value::to_raw_value`.
 | ||||||
|  |         #[ruma_api(body)] | ||||||
|  |         pub data: Box<RawJsonValue>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// A unique identifier for the event.
 | ||||||
|  |         // This is not declared required in r0.6.0, but that was a bug that has now been fixed:
 | ||||||
|  |         // https://github.com/matrix-org/matrix-doc/pull/2525
 | ||||||
|  |         pub event_id: EventId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								ruma-client-api/src/r0/message/get_message_events.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								ruma-client-api/src/r0/message/get_message_events.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | |||||||
|  | //! [GET /_matrix/client/r0/rooms/{roomId}/messages](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-messages)
 | ||||||
|  | 
 | ||||||
|  | use js_int::UInt; | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::{ | ||||||
|  |     collections::all::{RoomEvent, StateEvent}, | ||||||
|  |     EventJson, | ||||||
|  | }; | ||||||
|  | use ruma_identifiers::RoomId; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | 
 | ||||||
|  | use crate::r0::filter::RoomEventFilter; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get message events for a room.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_message_events", | ||||||
|  |         path: "/_matrix/client/r0/rooms/:room_id/messages", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The room to get events from.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub room_id: RoomId, | ||||||
|  | 
 | ||||||
|  |         /// The token to start returning events from.
 | ||||||
|  |         ///
 | ||||||
|  |         /// This token can be obtained from a
 | ||||||
|  |         /// prev_batch token returned for each room by the sync API, or from a start or end token
 | ||||||
|  |         /// returned by a previous request to this endpoint.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub from: String, | ||||||
|  | 
 | ||||||
|  |         /// The token to stop returning events at.
 | ||||||
|  |         ///
 | ||||||
|  |         /// This token can be obtained from a prev_batch
 | ||||||
|  |         /// token returned for each room by the sync endpoint, or from a start or end token returned
 | ||||||
|  |         /// by a previous request to this endpoint.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub to: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The direction to return events from.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub dir: Direction, | ||||||
|  | 
 | ||||||
|  |         /// The maximum number of events to return.
 | ||||||
|  |         ///
 | ||||||
|  |         /// Default: 10.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         pub limit: Option<UInt>, | ||||||
|  | 
 | ||||||
|  |         /// A RoomEventFilter to filter returned events with.
 | ||||||
|  |         #[ruma_api(query)] | ||||||
|  |         #[serde(
 | ||||||
|  |             with = "ruma_serde::json_string", | ||||||
|  |             default, | ||||||
|  |             skip_serializing_if = "Option::is_none" | ||||||
|  |         )] | ||||||
|  |         pub filter: Option<RoomEventFilter>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The token the pagination starts from.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub start: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The token the pagination ends at.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub end: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// A list of room events.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |         pub chunk: Vec<EventJson<RoomEvent>>, | ||||||
|  | 
 | ||||||
|  |         /// A list of state events relevant to showing the `chunk`.
 | ||||||
|  |         #[serde(default, skip_serializing_if = "Vec::is_empty")] | ||||||
|  |         pub state: Vec<EventJson<StateEvent>>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// The direction to return events from.
 | ||||||
|  | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] | ||||||
|  | pub enum Direction { | ||||||
|  |     /// Return events backwards in time from the requested `from` token.
 | ||||||
|  |     #[serde(rename = "b")] | ||||||
|  |     Backward, | ||||||
|  | 
 | ||||||
|  |     /// Return events forwards in time from the requested `from` token.
 | ||||||
|  |     #[serde(rename = "f")] | ||||||
|  |     Forward, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use super::{Direction, Request}; | ||||||
|  | 
 | ||||||
|  |     use std::convert::{TryFrom, TryInto}; | ||||||
|  | 
 | ||||||
|  |     use js_int::UInt; | ||||||
|  |     use ruma_identifiers::RoomId; | ||||||
|  | 
 | ||||||
|  |     use crate::r0::filter::{LazyLoadOptions, RoomEventFilter}; | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_some_room_event_filter() { | ||||||
|  |         let room_id = RoomId::try_from("!roomid:example.org").unwrap(); | ||||||
|  |         let filter = RoomEventFilter { | ||||||
|  |             lazy_load_options: LazyLoadOptions::Enabled { | ||||||
|  |                 include_redundant_members: true, | ||||||
|  |             }, | ||||||
|  |             rooms: Some(vec![room_id.clone()]), | ||||||
|  |             not_rooms: vec!["room".into(), "room2".into(), "room3".into()], | ||||||
|  |             not_types: vec!["type".into()], | ||||||
|  |             ..Default::default() | ||||||
|  |         }; | ||||||
|  |         let req = Request { | ||||||
|  |             room_id, | ||||||
|  |             from: "token".into(), | ||||||
|  |             to: Some("token2".into()), | ||||||
|  |             dir: Direction::Backward, | ||||||
|  |             limit: Some(UInt::from(0u32)), | ||||||
|  |             filter: Some(filter), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let request: http::Request<Vec<u8>> = req.try_into().unwrap(); | ||||||
|  |         assert_eq!( | ||||||
|  |             "from=token&to=token2&dir=b&limit=0&filter=%7B%22not_types%22%3A%5B%22type%22%5D%2C%22not_rooms%22%3A%5B%22room%22%2C%22room2%22%2C%22room3%22%5D%2C%22rooms%22%3A%5B%22%21roomid%3Aexample.org%22%5D%2C%22lazy_load_members%22%3Atrue%2C%22include_redundant_members%22%3Atrue%7D", | ||||||
|  |             request.uri().query().unwrap() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_none_room_event_filter() { | ||||||
|  |         let room_id = RoomId::try_from("!roomid:example.org").unwrap(); | ||||||
|  |         let req = Request { | ||||||
|  |             room_id, | ||||||
|  |             from: "token".into(), | ||||||
|  |             to: Some("token2".into()), | ||||||
|  |             dir: Direction::Backward, | ||||||
|  |             limit: Some(UInt::from(0u32)), | ||||||
|  |             filter: None, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let request: http::Request<Vec<u8>> = req.try_into().unwrap(); | ||||||
|  |         assert_eq!( | ||||||
|  |             "from=token&to=token2&dir=b&limit=0", | ||||||
|  |             request.uri().query().unwrap(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_serialize_default_room_event_filter() { | ||||||
|  |         let room_id = RoomId::try_from("!roomid:example.org").unwrap(); | ||||||
|  |         let req = Request { | ||||||
|  |             room_id, | ||||||
|  |             from: "token".into(), | ||||||
|  |             to: Some("token2".into()), | ||||||
|  |             dir: Direction::Backward, | ||||||
|  |             limit: Some(UInt::from(0u32)), | ||||||
|  |             filter: Some(RoomEventFilter::default()), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let request: http::Request<Vec<u8>> = req.try_into().unwrap(); | ||||||
|  |         assert_eq!( | ||||||
|  |             "from=token&to=token2&dir=b&limit=0&filter=%7B%7D", | ||||||
|  |             request.uri().query().unwrap(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								ruma-client-api/src/r0/presence.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ruma-client-api/src/r0/presence.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | //! Endpoints for user presence.
 | ||||||
|  | 
 | ||||||
|  | pub mod get_presence; | ||||||
|  | pub mod set_presence; | ||||||
							
								
								
									
										47
									
								
								ruma-client-api/src/r0/presence/get_presence.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								ruma-client-api/src/r0/presence/get_presence.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | //! [GET /_matrix/client/r0/presence/{userId}/status](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-presence-userid-status)
 | ||||||
|  | 
 | ||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::presence::PresenceState; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get presence status for this user.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_presence", | ||||||
|  |         path: "/_matrix/client/r0/presence/:user_id/status", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose presence state will be retrieved.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The state message for this user if one was set.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub status_msg: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// Whether or not the user is currently active.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub currently_active: Option<bool>, | ||||||
|  | 
 | ||||||
|  |         /// The length of time in milliseconds since an action was performed by the user.
 | ||||||
|  |         #[serde(
 | ||||||
|  |             with = "ruma_serde::duration::opt_ms", | ||||||
|  |             default, | ||||||
|  |             skip_serializing_if = "Option::is_none", | ||||||
|  |         )] | ||||||
|  |         pub last_active_ago: Option<Duration>, | ||||||
|  | 
 | ||||||
|  |         /// The user's presence state.
 | ||||||
|  |         pub presence: PresenceState, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								ruma-client-api/src/r0/presence/set_presence.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ruma-client-api/src/r0/presence/set_presence.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/presence/{userId}/status](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-presence-userid-status)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_events::presence::PresenceState; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Set presence status for this user.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "set_presence", | ||||||
|  |         path: "/_matrix/client/r0/presence/:user_id/status", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose presence state will be updated.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The new presence state.
 | ||||||
|  |         pub presence: PresenceState, | ||||||
|  | 
 | ||||||
|  |         /// The status message to attach to this state.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub status_msg: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								ruma-client-api/src/r0/profile.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								ruma-client-api/src/r0/profile.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | //! Endpoints for user profiles.
 | ||||||
|  | 
 | ||||||
|  | pub mod get_avatar_url; | ||||||
|  | pub mod get_display_name; | ||||||
|  | pub mod get_profile; | ||||||
|  | pub mod set_avatar_url; | ||||||
|  | pub mod set_display_name; | ||||||
							
								
								
									
										29
									
								
								ruma-client-api/src/r0/profile/get_avatar_url.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								ruma-client-api/src/r0/profile/get_avatar_url.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | //! [GET /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-profile-userid-avatar-url)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get the avatar URL of a user.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_avatar_url", | ||||||
|  |         path: "/_matrix/client/r0/profile/:user_id/avatar_url", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose avatar URL will be retrieved.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The user's avatar URL, if set.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub avatar_url: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								ruma-client-api/src/r0/profile/get_display_name.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								ruma-client-api/src/r0/profile/get_display_name.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | //! [GET /_matrix/client/r0/profile/{userId}/displayname](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-profile-userid-displayname)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get the display name of a user.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_display_name", | ||||||
|  |         path: "/_matrix/client/r0/profile/:user_id/displayname", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose display name will be retrieved.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The user's display name, if set.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub displayname: Option<String> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								ruma-client-api/src/r0/profile/get_profile.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ruma-client-api/src/r0/profile/get_profile.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | //! [GET /_matrix/client/r0/profile/{userId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-profile-userid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Get all profile information of an user.", | ||||||
|  |         method: GET, | ||||||
|  |         name: "get_profile", | ||||||
|  |         path: "/_matrix/client/r0/profile/:user_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: false, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose profile will be retrieved.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response { | ||||||
|  |         /// The user's avatar URL, if set.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub avatar_url: Option<String>, | ||||||
|  | 
 | ||||||
|  |         /// The user's display name, if set.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub displayname: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								ruma-client-api/src/r0/profile/set_avatar_url.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ruma-client-api/src/r0/profile/set_avatar_url.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-profile-userid-avatar-url)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Set the avatar URL of the user.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "set_avatar_url", | ||||||
|  |         path: "/_matrix/client/r0/profile/:user_id/avatar_url", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose avatar URL will be set.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The new avatar URL for the user.
 | ||||||
|  |         ///
 | ||||||
|  |         /// `None` is used to unset the avatar.
 | ||||||
|  |         pub avatar_url: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								ruma-client-api/src/r0/profile/set_display_name.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								ruma-client-api/src/r0/profile/set_display_name.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | //! [PUT /_matrix/client/r0/profile/{userId}/displayname](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-profile-userid-displayname)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | use ruma_identifiers::UserId; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "Set the display name of the user.", | ||||||
|  |         method: PUT, | ||||||
|  |         name: "set_display_name", | ||||||
|  |         path: "/_matrix/client/r0/profile/:user_id/displayname", | ||||||
|  |         rate_limited: true, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The user whose display name will be set.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub user_id: UserId, | ||||||
|  | 
 | ||||||
|  |         /// The new display name for the user.
 | ||||||
|  |         #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |         pub displayname: Option<String>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
							
								
								
									
										140
									
								
								ruma-client-api/src/r0/push.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								ruma-client-api/src/r0/push.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | |||||||
|  | //! Endpoints for push notifications.
 | ||||||
|  | 
 | ||||||
|  | use std::convert::TryFrom; | ||||||
|  | 
 | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  | use strum::{Display, EnumString}; | ||||||
|  | 
 | ||||||
|  | pub mod delete_pushrule; | ||||||
|  | pub mod get_notifications; | ||||||
|  | pub mod get_pushers; | ||||||
|  | pub mod get_pushrule; | ||||||
|  | pub mod get_pushrule_actions; | ||||||
|  | pub mod get_pushrule_enabled; | ||||||
|  | pub mod get_pushrules_all; | ||||||
|  | pub mod get_pushrules_global_scope; | ||||||
|  | pub mod set_pusher; | ||||||
|  | pub mod set_pushrule; | ||||||
|  | pub mod set_pushrule_actions; | ||||||
|  | pub mod set_pushrule_enabled; | ||||||
|  | 
 | ||||||
|  | pub use ruma_common::push::Action; | ||||||
|  | pub use ruma_events::push_rules::PushCondition; | ||||||
|  | 
 | ||||||
|  | /// The kinds of push rules that are available
 | ||||||
|  | #[derive(
 | ||||||
|  |     Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Display, EnumString, | ||||||
|  | )] | ||||||
|  | #[serde(rename_all = "snake_case")] | ||||||
|  | #[strum(serialize_all = "snake_case")] | ||||||
|  | pub enum RuleKind { | ||||||
|  |     /// User-configured rules that override all other kinds
 | ||||||
|  |     Override, | ||||||
|  | 
 | ||||||
|  |     /// Lowest priority user-defined rules
 | ||||||
|  |     Underride, | ||||||
|  | 
 | ||||||
|  |     /// Sender-specific rules
 | ||||||
|  |     Sender, | ||||||
|  | 
 | ||||||
|  |     /// Room-specific rules
 | ||||||
|  |     Room, | ||||||
|  | 
 | ||||||
|  |     /// Content-specific rules
 | ||||||
|  |     Content, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TryFrom<&'_ str> for RuleKind { | ||||||
|  |     type Error = strum::ParseError; | ||||||
|  | 
 | ||||||
|  |     fn try_from(s: &str) -> Result<Self, Self::Error> { | ||||||
|  |         s.parse() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A push rule
 | ||||||
|  | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||||
|  | pub struct PushRule { | ||||||
|  |     /// The actions to perform when this rule is matched.
 | ||||||
|  |     pub actions: Vec<Action>, | ||||||
|  | 
 | ||||||
|  |     /// Whether this is a default rule, or has been set explicitly.
 | ||||||
|  |     pub default: bool, | ||||||
|  | 
 | ||||||
|  |     /// Whether the push rule is enabled or not.
 | ||||||
|  |     pub enabled: bool, | ||||||
|  | 
 | ||||||
|  |     /// The ID of this rule.
 | ||||||
|  |     pub rule_id: String, | ||||||
|  | 
 | ||||||
|  |     /// The conditions that must hold true for an event in order for a rule to be applied to an event. A rule with no conditions always matches.
 | ||||||
|  |     /// Only applicable to underride and override rules.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub conditions: Option<Vec<PushCondition>>, | ||||||
|  | 
 | ||||||
|  |     /// The glob-style pattern to match against. Only applicable to content rules.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub pattern: Option<String>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Defines a pusher
 | ||||||
|  | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||||
|  | pub struct Pusher { | ||||||
|  |     /// This is a unique identifier for this pusher. Max length, 512 bytes.
 | ||||||
|  |     pub pushkey: String, | ||||||
|  | 
 | ||||||
|  |     /// The kind of the pusher. If set to None in a call to set_pusher, this
 | ||||||
|  |     /// will delete the pusher
 | ||||||
|  |     pub kind: Option<PusherKind>, | ||||||
|  | 
 | ||||||
|  |     /// This is a reverse-DNS style identifier for the application. Max length, 64 chars.
 | ||||||
|  |     pub app_id: String, | ||||||
|  | 
 | ||||||
|  |     /// A string that will allow the user to identify what application owns this pusher.
 | ||||||
|  |     pub app_display_name: String, | ||||||
|  | 
 | ||||||
|  |     /// A string that will allow the user to identify what device owns this pusher.
 | ||||||
|  |     pub device_display_name: String, | ||||||
|  | 
 | ||||||
|  |     /// This string determines which set of device specific rules this pusher executes.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub profile_tag: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// The preferred language for receiving notifications (e.g. 'en' or 'en-US')
 | ||||||
|  |     pub lang: String, | ||||||
|  | 
 | ||||||
|  |     /// Information for the pusher implementation itself.
 | ||||||
|  |     pub data: PusherData, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Which kind a pusher is
 | ||||||
|  | #[derive(Clone, Copy, Debug, Serialize, Deserialize)] | ||||||
|  | #[serde(rename_all = "snake_case")] | ||||||
|  | pub enum PusherKind { | ||||||
|  |     /// A pusher that sends HTTP pokes.
 | ||||||
|  |     Http, | ||||||
|  | 
 | ||||||
|  |     /// A pusher that emails the user with unread notifications.
 | ||||||
|  |     Email, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Information for the pusher implementation itself.
 | ||||||
|  | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||||
|  | pub struct PusherData { | ||||||
|  |     /// Required if the pusher's kind is http. The URL to use to send notifications to.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub url: Option<String>, | ||||||
|  | 
 | ||||||
|  |     /// The format to use when sending notifications to the Push Gateway.
 | ||||||
|  |     #[serde(skip_serializing_if = "Option::is_none")] | ||||||
|  |     pub format: Option<PushFormat>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A special format that the homeserver should use when sending notifications to a Push Gateway.
 | ||||||
|  | /// Currently, only "event_id_only" is supported as of [Push Gateway API r0.1.1](https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour)
 | ||||||
|  | #[derive(Clone, Copy, Debug, Serialize, Deserialize)] | ||||||
|  | #[serde(rename_all = "snake_case")] | ||||||
|  | pub enum PushFormat { | ||||||
|  |     /// Require the homeserver to only send a reduced set of fields in the push.
 | ||||||
|  |     EventIdOnly, | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								ruma-client-api/src/r0/push/delete_pushrule.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ruma-client-api/src/r0/push/delete_pushrule.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | //! [DELETE /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-pushrules-scope-kind-ruleid)
 | ||||||
|  | 
 | ||||||
|  | use ruma_api::ruma_api; | ||||||
|  | 
 | ||||||
|  | use super::RuleKind; | ||||||
|  | 
 | ||||||
|  | ruma_api! { | ||||||
|  |     metadata { | ||||||
|  |         description: "This endpoint removes the push rule defined in the path.", | ||||||
|  |         method: DELETE, | ||||||
|  |         name: "delete_pushrule", | ||||||
|  |         path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id", | ||||||
|  |         rate_limited: false, | ||||||
|  |         requires_authentication: true, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     request { | ||||||
|  |         /// The scope to delete from. 'global' to specify global rules.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub scope: String, | ||||||
|  | 
 | ||||||
|  |         /// The kind of rule
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub kind: RuleKind, | ||||||
|  | 
 | ||||||
|  |         /// The identifier for the rule.
 | ||||||
|  |         #[ruma_api(path)] | ||||||
|  |         pub rule_id: String, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     response {} | ||||||
|  | 
 | ||||||
|  |     error: crate::Error | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user