Add RoomIdOrAliasId
This commit is contained in:
parent
9d42cd5413
commit
5c729ca988
181
src/lib.rs
181
src/lib.rs
@ -126,6 +126,31 @@ pub struct RoomId {
|
||||
port: u16,
|
||||
}
|
||||
|
||||
/// A Matrix room ID or a Matrix room alias ID.
|
||||
///
|
||||
/// A `RoomIdOrAliasId` is converted from a string slice, and can be converted back into a
|
||||
/// string as needed.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(try_from)]
|
||||
/// # use std::convert::TryFrom;
|
||||
/// # use ruma_identifiers::RoomIdOrAliasId;
|
||||
/// assert_eq!(
|
||||
/// RoomIdOrAliasId::try_from("#ruma:example.com").unwrap().to_string(),
|
||||
/// "#ruma:example.com"
|
||||
/// );
|
||||
/// assert_eq!(
|
||||
/// RoomIdOrAliasId::try_from("!n8f893n9:example.com").unwrap().to_string(),
|
||||
/// "!n8f893n9:example.com"
|
||||
/// );
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum RoomIdOrAliasId {
|
||||
/// A Matrix room alias ID.
|
||||
RoomAliasId(RoomAliasId),
|
||||
/// A Matrix room ID.
|
||||
RoomId(RoomId),
|
||||
}
|
||||
|
||||
/// A Matrix user ID.
|
||||
///
|
||||
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
|
||||
@ -150,6 +175,7 @@ pub struct UserId {
|
||||
struct EventIdVisitor;
|
||||
struct RoomAliasIdVisitor;
|
||||
struct RoomIdVisitor;
|
||||
struct RoomIdOrAliasIdVisitor;
|
||||
struct UserIdVisitor;
|
||||
|
||||
fn display(f: &mut Formatter, sigil: char, localpart: &str, hostname: &Host, port: u16)
|
||||
@ -165,17 +191,23 @@ fn generate_localpart(length: usize) -> String {
|
||||
thread_rng().gen_ascii_chars().take(length).collect()
|
||||
}
|
||||
|
||||
fn parse_id<'a>(required_sigil: char, id: &'a str) -> Result<(&'a str, Host, u16), Error> {
|
||||
fn validate_id<'a>(id: &'a str) -> Result<(), Error> {
|
||||
if id.len() > MAX_BYTES {
|
||||
return Err(Error::MaximumLengthExceeded);
|
||||
}
|
||||
|
||||
let mut chars = id.chars();
|
||||
|
||||
if id.len() < MIN_CHARS {
|
||||
return Err(Error::MinimumLengthNotSatisfied);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_id<'a>(required_sigil: char, id: &'a str) -> Result<(&'a str, Host, u16), Error> {
|
||||
validate_id(id)?;
|
||||
|
||||
let mut chars = id.chars();
|
||||
|
||||
let sigil = chars.nth(0).expect("ID missing first character.");
|
||||
|
||||
if sigil != required_sigil {
|
||||
@ -370,6 +402,19 @@ impl Display for RoomId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RoomIdOrAliasId {
|
||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||
match *self {
|
||||
RoomIdOrAliasId::RoomAliasId(ref room_alias_id) => {
|
||||
display(f, '#', &room_alias_id.alias, &room_alias_id.hostname, room_alias_id.port)
|
||||
}
|
||||
RoomIdOrAliasId::RoomId(ref room_id) => {
|
||||
display(f, '!', &room_id.opaque_id, &room_id.hostname, room_id.port)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for UserId {
|
||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||
display(f, '@', &self.localpart, &self.hostname, self.port)
|
||||
@ -394,6 +439,19 @@ impl Serialize for RoomId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for RoomIdOrAliasId {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
RoomIdOrAliasId::RoomAliasId(ref room_alias_id) => {
|
||||
serializer.serialize_str(&room_alias_id.to_string())
|
||||
}
|
||||
RoomIdOrAliasId::RoomId(ref room_id) => {
|
||||
serializer.serialize_str(&room_id.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for UserId {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
serializer.serialize_str(&self.to_string())
|
||||
@ -418,6 +476,12 @@ impl Deserialize for RoomId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for RoomIdOrAliasId {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
deserializer.deserialize(RoomIdOrAliasIdVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for UserId {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
deserializer.deserialize(UserIdVisitor)
|
||||
@ -478,6 +542,35 @@ impl<'a> TryFrom<&'a str> for RoomId {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a str> for RoomIdOrAliasId {
|
||||
type Err = Error;
|
||||
|
||||
/// Attempts to create a new Matrix room ID or a room alias ID from a string representation.
|
||||
///
|
||||
/// The string must either
|
||||
/// include the leading ! sigil, the opaque ID, a literal colon, and a valid server name or
|
||||
/// include the leading # sigil, the alias, a literal colon, and a valid server name.
|
||||
fn try_from(room_id_or_alias_id: &'a str) -> Result<Self, Error> {
|
||||
validate_id(room_id_or_alias_id)?;
|
||||
|
||||
let mut chars = room_id_or_alias_id.chars();
|
||||
|
||||
let sigil = chars.nth(0).expect("ID missing first character.");
|
||||
|
||||
match sigil {
|
||||
'#' => {
|
||||
let room_alias_id = RoomAliasId::try_from(room_id_or_alias_id)?;
|
||||
Ok(RoomIdOrAliasId::RoomAliasId(room_alias_id))
|
||||
}
|
||||
'!' => {
|
||||
let room_id = RoomId::try_from(room_id_or_alias_id)?;
|
||||
Ok(RoomIdOrAliasId::RoomId(room_id))
|
||||
}
|
||||
_ => Err(Error::MissingSigil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a str> for UserId {
|
||||
type Err = Error;
|
||||
|
||||
@ -534,6 +627,17 @@ impl Visitor for RoomIdVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor for RoomIdOrAliasIdVisitor {
|
||||
type Value = RoomIdOrAliasId;
|
||||
|
||||
fn visit_str<E>(&mut self, v: &str) -> Result<Self::Value, E> where E: SerdeError {
|
||||
match RoomIdOrAliasId::try_from(v) {
|
||||
Ok(room_id_or_alias_id) => Ok(room_id_or_alias_id),
|
||||
Err(_) => Err(SerdeError::custom("invalid ID")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor for UserIdVisitor {
|
||||
type Value = UserId;
|
||||
|
||||
@ -619,6 +723,7 @@ mod diesel_integration {
|
||||
diesel_impl!(EventId);
|
||||
diesel_impl!(RoomAliasId);
|
||||
diesel_impl!(RoomId);
|
||||
diesel_impl!(RoomIdOrAliasId);
|
||||
diesel_impl!(UserId);
|
||||
}
|
||||
|
||||
@ -628,7 +733,7 @@ mod tests {
|
||||
|
||||
use serde_json::{from_str, to_string};
|
||||
|
||||
use super::{Error, EventId, RoomAliasId, RoomId, UserId};
|
||||
use super::{Error, EventId, RoomAliasId, RoomId, RoomIdOrAliasId, UserId};
|
||||
|
||||
#[test]
|
||||
fn valid_event_id() {
|
||||
@ -905,6 +1010,74 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_room_id_or_alias_id_with_a_room_alias_id() {
|
||||
assert_eq!(
|
||||
RoomIdOrAliasId::try_from("#ruma:example.com")
|
||||
.expect("Failed to create RoomAliasId.")
|
||||
.to_string(),
|
||||
"#ruma:example.com"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_room_id_or_alias_id_with_a_room_id() {
|
||||
assert_eq!(
|
||||
RoomIdOrAliasId::try_from("!29fhd83h92h0:example.com")
|
||||
.expect("Failed to create RoomId.")
|
||||
.to_string(),
|
||||
"!29fhd83h92h0:example.com"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_sigil_for_room_id_or_alias_id() {
|
||||
assert_eq!(
|
||||
RoomIdOrAliasId::try_from("ruma:example.com").err().unwrap(),
|
||||
Error::MissingSigil
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_valid_room_id_or_alias_id_with_a_room_alias_id() {
|
||||
assert_eq!(
|
||||
to_string(
|
||||
&RoomIdOrAliasId::try_from("#ruma:example.com").expect("Failed to create RoomAliasId.")
|
||||
).expect("Failed to convert RoomAliasId to JSON."),
|
||||
r##""#ruma:example.com""##
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_valid_room_id_or_alias_id_with_a_room_id() {
|
||||
assert_eq!(
|
||||
to_string(
|
||||
&RoomIdOrAliasId::try_from("!29fhd83h92h0:example.com").expect("Failed to create RoomId.")
|
||||
).expect("Failed to convert RoomId to JSON."),
|
||||
r#""!29fhd83h92h0:example.com""#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_valid_room_id_or_alias_id_with_a_room_alias_id() {
|
||||
assert_eq!(
|
||||
from_str::<RoomIdOrAliasId>(
|
||||
r##""#ruma:example.com""##
|
||||
).expect("Failed to convert JSON to RoomAliasId"),
|
||||
RoomIdOrAliasId::try_from("#ruma:example.com").expect("Failed to create RoomAliasId.")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_valid_room_id_or_alias_id_with_a_room_id() {
|
||||
assert_eq!(
|
||||
from_str::<RoomIdOrAliasId>(
|
||||
r##""!29fhd83h92h0:example.com""##
|
||||
).expect("Failed to convert JSON to RoomId"),
|
||||
RoomIdOrAliasId::try_from("!29fhd83h92h0:example.com").expect("Failed to create RoomAliasId.")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_user_id() {
|
||||
assert_eq!(
|
||||
|
Loading…
x
Reference in New Issue
Block a user