use serde::Serialize;
use serde_with::skip_serializing_none;
use url::Url;
use crate::error::AccountManagementError;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "action")]
#[non_exhaustive]
pub enum AccountManagementActionFull {
#[serde(rename = "org.matrix.profile")]
Profile,
#[serde(rename = "org.matrix.sessions_list")]
SessionsList,
#[serde(rename = "org.matrix.session_view")]
SessionView {
device_id: String,
},
#[serde(rename = "org.matrix.session_end")]
SessionEnd {
device_id: String,
},
#[serde(rename = "org.matrix.account_deactivate")]
AccountDeactivate,
#[serde(rename = "org.matrix.cross_signing_reset")]
CrossSigningReset,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize)]
struct AccountManagementData {
#[serde(flatten)]
action: Option<AccountManagementActionFull>,
id_token_hint: Option<String>,
}
pub fn build_account_management_url(
mut account_management_uri: Url,
action: Option<AccountManagementActionFull>,
id_token_hint: Option<String>,
) -> Result<Url, AccountManagementError> {
let data = AccountManagementData {
action,
id_token_hint,
};
let extra_query = serde_urlencoded::to_string(data)?;
if !extra_query.is_empty() {
let mut full_query = account_management_uri
.query()
.map(ToOwned::to_owned)
.unwrap_or_default();
if !full_query.is_empty() {
full_query.push('&');
}
full_query.push_str(&extra_query);
account_management_uri.set_query(Some(&full_query));
}
Ok(account_management_uri)
}