use std::collections::BTreeMap;
use salvo::prelude::*;
use serde::{Deserialize, Serialize};
use crate::{OwnedRoomAliasId, OwnedUserId, PrivOwnedStr, UnixMillis, serde::StringEnum};
#[derive(ToSchema, Deserialize, Serialize, Clone, Default, Debug)]
pub struct Protocol {
pub user_fields: Vec<String>,
pub location_fields: Vec<String>,
#[serde(default)]
pub icon: String,
pub field_types: BTreeMap<String, FieldType>,
pub instances: Vec<ProtocolInstance>,
}
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct ProtocolInit {
pub user_fields: Vec<String>,
pub location_fields: Vec<String>,
pub icon: String,
pub field_types: BTreeMap<String, FieldType>,
pub instances: Vec<ProtocolInstance>,
}
impl From<ProtocolInit> for Protocol {
fn from(init: ProtocolInit) -> Self {
let ProtocolInit {
user_fields,
location_fields,
icon,
field_types,
instances,
} = init;
Self {
user_fields,
location_fields,
icon,
field_types,
instances,
}
}
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct ProtocolInstance {
pub desc: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<String>,
pub fields: BTreeMap<String, String>,
pub network_id: String,
#[cfg(feature = "unstable-unspecified")]
pub instance_id: String,
}
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct ProtocolInstanceInit {
pub desc: String,
pub fields: BTreeMap<String, String>,
pub network_id: String,
#[cfg(feature = "unstable-unspecified")]
pub instance_id: String,
}
impl From<ProtocolInstanceInit> for ProtocolInstance {
fn from(init: ProtocolInstanceInit) -> Self {
let ProtocolInstanceInit {
desc,
fields,
network_id,
#[cfg(feature = "unstable-unspecified")]
instance_id,
} = init;
Self {
desc,
icon: None,
fields,
network_id,
#[cfg(feature = "unstable-unspecified")]
instance_id,
}
}
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct FieldType {
pub regexp: String,
pub placeholder: String,
}
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct FieldTypeInit {
pub regexp: String,
pub placeholder: String,
}
impl From<FieldTypeInit> for FieldType {
fn from(init: FieldTypeInit) -> Self {
let FieldTypeInit { regexp, placeholder } = init;
Self { regexp, placeholder }
}
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct Location {
pub alias: OwnedRoomAliasId,
pub protocol: String,
pub fields: BTreeMap<String, String>,
}
impl Location {
pub fn new(alias: OwnedRoomAliasId, protocol: String, fields: BTreeMap<String, String>) -> Self {
Self {
alias,
protocol,
fields,
}
}
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct User {
pub user_id: OwnedUserId,
pub protocol: String,
pub fields: BTreeMap<String, String>,
}
impl User {
pub fn new(user_id: OwnedUserId, protocol: String, fields: BTreeMap<String, String>) -> Self {
Self {
user_id,
protocol,
fields,
}
}
}
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(ToSchema, Clone, PartialEq, Eq, StringEnum)]
#[palpo_enum(rename_all = "lowercase")]
#[non_exhaustive]
pub enum Medium {
Email,
Msisdn,
#[doc(hidden)]
#[salvo(schema(value_type = String))]
_Custom(PrivOwnedStr),
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
#[cfg_attr(test, derive(PartialEq))]
pub struct ThirdPartyIdentifier {
pub address: String,
pub medium: Medium,
pub validated_at: UnixMillis,
pub added_at: UnixMillis,
}
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct ThirdPartyIdentifierInit {
pub address: String,
pub medium: Medium,
pub validated_at: UnixMillis,
pub added_at: UnixMillis,
}
impl From<ThirdPartyIdentifierInit> for ThirdPartyIdentifier {
fn from(init: ThirdPartyIdentifierInit) -> Self {
let ThirdPartyIdentifierInit {
address,
medium,
validated_at,
added_at,
} = init;
ThirdPartyIdentifier {
address,
medium,
validated_at,
added_at,
}
}
}
#[derive(ToSchema, Serialize, Default, Debug)]
pub struct ProtocolsResBody(
BTreeMap<String, Protocol>,
);
impl ProtocolsResBody {
pub fn new(protocols: BTreeMap<String, Protocol>) -> Self {
Self(protocols)
}
}
#[derive(ToSchema, Serialize, Clone, Default, Debug)]
pub struct ProtocolResBody(
pub Protocol,
);
impl ProtocolResBody {
pub fn new(protocol: Protocol) -> Self {
Self(protocol)
}
}
#[derive(ToSchema, Serialize, Default, Debug)]
pub struct LocationsResBody(
pub Vec<Location>,
);
impl LocationsResBody {
pub fn new(locations: Vec<Location>) -> Self {
Self(locations)
}
}
#[derive(ToSchema, Serialize, Default, Debug)]
pub struct UsersResBody(
pub Vec<User>,
);
impl UsersResBody {
pub fn new(users: Vec<User>) -> Self {
Self(users)
}
}
#[cfg(test)]
mod tests {
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
use super::{Medium, ThirdPartyIdentifier};
use crate::UnixMillis;
#[test]
fn third_party_identifier_serde() {
let third_party_id = ThirdPartyIdentifier {
address: "monkey@banana.island".into(),
medium: Medium::Email,
validated_at: UnixMillis(1_535_176_800_000_u64.try_into().unwrap()),
added_at: UnixMillis(1_535_336_848_756_u64.try_into().unwrap()),
};
let third_party_id_serialized = json!({
"medium": "email",
"address": "monkey@banana.island",
"validated_at": 1_535_176_800_000_u64,
"added_at": 1_535_336_848_756_u64
});
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());
}
}