pub mod v3 {
use std::collections::btree_map;
use ruma_common::{
OwnedUserId,
api::{auth_scheme::NoAccessToken, request, response},
metadata,
profile::{ProfileFieldName, ProfileFieldValue, StaticProfileField, UserProfile},
};
use serde_json::Value as JsonValue;
metadata! {
method: GET,
rate_limited: false,
authentication: NoAccessToken,
history: {
1.0 => "/_matrix/client/r0/profile/{user_id}",
1.1 => "/_matrix/client/v3/profile/{user_id}",
}
}
#[request]
pub struct Request {
#[ruma_api(path)]
pub user_id: OwnedUserId,
}
#[response]
#[derive(Default)]
pub struct Response {
#[ruma_api(body)]
pub data: UserProfile,
}
impl Request {
pub fn new(user_id: OwnedUserId) -> Self {
Self { user_id }
}
}
impl Response {
pub fn new() -> Self {
Self::default()
}
pub fn get(&self, field: &str) -> Option<&JsonValue> {
self.data.get(field)
}
pub fn get_static<F: StaticProfileField>(
&self,
) -> Result<Option<F::Value>, serde_json::Error> {
self.data.get_static::<F>()
}
pub fn iter(&self) -> btree_map::Iter<'_, String, JsonValue> {
self.data.iter()
}
pub fn set(&mut self, field: String, value: JsonValue) {
self.data.set(field, value);
}
}
impl From<UserProfile> for Response {
fn from(value: UserProfile) -> Self {
Self { data: value }
}
}
impl FromIterator<(String, JsonValue)> for Response {
fn from_iter<T: IntoIterator<Item = (String, JsonValue)>>(iter: T) -> Self {
Self { data: UserProfile::from_iter(iter) }
}
}
impl FromIterator<(ProfileFieldName, JsonValue)> for Response {
fn from_iter<T: IntoIterator<Item = (ProfileFieldName, JsonValue)>>(iter: T) -> Self {
Self { data: UserProfile::from_iter(iter) }
}
}
impl FromIterator<ProfileFieldValue> for Response {
fn from_iter<T: IntoIterator<Item = ProfileFieldValue>>(iter: T) -> Self {
Self { data: UserProfile::from_iter(iter) }
}
}
impl Extend<(String, JsonValue)> for Response {
fn extend<T: IntoIterator<Item = (String, JsonValue)>>(&mut self, iter: T) {
self.data.extend(iter);
}
}
impl Extend<(ProfileFieldName, JsonValue)> for Response {
fn extend<T: IntoIterator<Item = (ProfileFieldName, JsonValue)>>(&mut self, iter: T) {
self.data.extend(iter);
}
}
impl Extend<ProfileFieldValue> for Response {
fn extend<T: IntoIterator<Item = ProfileFieldValue>>(&mut self, iter: T) {
self.data.extend(iter);
}
}
impl IntoIterator for Response {
type Item = (String, JsonValue);
type IntoIter = btree_map::IntoIter<String, JsonValue>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::v3::Response;
#[test]
#[cfg(feature = "server")]
fn serialize_response() {
use ruma_common::{
api::OutgoingResponseExt as _, owned_mxc_uri, profile::ProfileFieldValue,
};
use serde_json::{Value as JsonValue, from_slice as from_json_slice};
let response = [
ProfileFieldValue::AvatarUrl(owned_mxc_uri!("mxc://localhost/abcdef")),
ProfileFieldValue::DisplayName("Alice".to_owned()),
ProfileFieldValue::new("custom_field", "value".into()).unwrap(),
]
.into_iter()
.collect::<Response>();
let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
assert_eq!(
from_json_slice::<JsonValue>(http_response.body().as_ref()).unwrap(),
json!({
"avatar_url": "mxc://localhost/abcdef",
"displayname": "Alice",
"custom_field": "value",
})
);
}
#[test]
#[cfg(feature = "client")]
fn deserialize_response() {
use ruma_common::api::IncomingResponseExt as _;
use crate::profile::{AvatarUrl, DisplayName};
let body = json!({
"avatar_url": "mxc://localhost/abcdef",
"displayname": "Alice",
"custom_field": "value",
})
.to_string();
let response =
Response::try_from_http_response(http::Response::new(body.as_bytes())).unwrap();
assert_eq!(response.get_static::<AvatarUrl>().unwrap().unwrap(), "mxc://localhost/abcdef");
assert_eq!(response.get_static::<DisplayName>().unwrap().unwrap(), "Alice");
assert_eq!(response.get("custom_field").unwrap().as_str().unwrap(), "value");
let body = json!({
"custom_field": null,
})
.to_string();
let response =
Response::try_from_http_response(http::Response::new(body.as_bytes())).unwrap();
assert_eq!(response.get_static::<AvatarUrl>().unwrap(), None);
assert_eq!(response.get_static::<DisplayName>().unwrap(), None);
assert!(response.get("custom_field").unwrap().is_null());
}
}