identifiers: Add more conversion functions
This commit is contained in:
parent
f8492db766
commit
046668466c
@ -10,21 +10,23 @@ pub struct DeviceKeyId<T> {
|
||||
colon_idx: NonZeroU8,
|
||||
}
|
||||
|
||||
impl<T> DeviceKeyId<T> {
|
||||
impl<T> DeviceKeyId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `DeviceKeyId`.
|
||||
pub fn as_ref(&self) -> DeviceKeyId<&str> {
|
||||
DeviceKeyId { full_id: self.full_id.as_ref(), colon_idx: self.colon_idx }
|
||||
}
|
||||
|
||||
/// Returns key algorithm of the device key ID.
|
||||
pub fn algorithm(&self) -> DeviceKeyAlgorithm
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn algorithm(&self) -> DeviceKeyAlgorithm {
|
||||
DeviceKeyAlgorithm::from_str(&self.full_id.as_ref()[..self.colon_idx.get() as usize])
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns device ID of the device key ID.
|
||||
pub fn device_id(&self) -> DeviceIdRef<'_>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn device_id(&self) -> DeviceIdRef<'_> {
|
||||
&self.full_id.as_ref()[self.colon_idx.get() as usize + 1..]
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,10 @@ pub struct EventId<T> {
|
||||
colon_idx: Option<NonZeroU8>,
|
||||
}
|
||||
|
||||
impl<T> EventId<T> {
|
||||
impl<T> EventId<T>
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
/// Attempts to generate an `EventId` for the given origin server with a localpart consisting
|
||||
/// of 18 random ASCII characters. This should only be used for events in the original format
|
||||
/// as used by Matrix room versions 1 and 2.
|
||||
@ -55,24 +58,28 @@ impl<T> EventId<T> {
|
||||
/// parsed as a valid host.
|
||||
#[cfg(feature = "rand")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
|
||||
pub fn new(server_name: ServerNameRef<'_>) -> Self
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
pub fn new(server_name: ServerNameRef<'_>) -> Self {
|
||||
use crate::generate_localpart;
|
||||
|
||||
let full_id = format!("${}:{}", generate_localpart(18), server_name).into();
|
||||
|
||||
Self { full_id, colon_idx: NonZeroU8::new(19) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EventId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `EventId`.
|
||||
pub fn as_ref(&self) -> EventId<&str> {
|
||||
EventId { full_id: self.full_id.as_ref(), colon_idx: self.colon_idx }
|
||||
}
|
||||
|
||||
/// Returns the event's unique ID. For the original event format as used by Matrix room
|
||||
/// versions 1 and 2, this is the "localpart" that precedes the homeserver. For later formats,
|
||||
/// this is the entire ID without the leading $ sigil.
|
||||
pub fn localpart(&self) -> &str
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn localpart(&self) -> &str {
|
||||
let idx = match self.colon_idx {
|
||||
Some(idx) => idx.get() as usize,
|
||||
None => self.full_id.as_ref().len(),
|
||||
@ -84,10 +91,7 @@ impl<T> EventId<T> {
|
||||
/// Returns the server name of the event ID.
|
||||
///
|
||||
/// Only applicable to events in the original format as used by Matrix room versions 1 and 2.
|
||||
pub fn server_name(&self) -> Option<ServerNameRef<'_>>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn server_name(&self) -> Option<ServerNameRef<'_>> {
|
||||
self.colon_idx.map(|idx| {
|
||||
ServerNameRef::try_from(&self.full_id.as_ref()[idx.get() as usize + 1..]).unwrap()
|
||||
})
|
||||
@ -162,7 +166,7 @@ mod tests {
|
||||
let server_name =
|
||||
ServerNameRef::try_from("example.com").expect("Failed to parse ServerName");
|
||||
let event_id = EventId::new(server_name);
|
||||
let id_str: &str = event_id.as_ref();
|
||||
let id_str = event_id.as_str();
|
||||
|
||||
assert!(id_str.starts_with('$'));
|
||||
assert_eq!(id_str.len(), 31);
|
||||
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use strum::{AsRefStr, Display, EnumString};
|
||||
|
||||
/// The basic key algorithms in the specification
|
||||
/// The basic key algorithms in the specification.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsRefStr, Display, EnumString)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[non_exhaustive]
|
||||
@ -23,6 +23,7 @@ pub enum DeviceKeyAlgorithm {
|
||||
SignedCurve25519,
|
||||
}
|
||||
|
||||
/// The server key algorithms defined in the Matrix spec.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsRefStr, Display, EnumString)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[non_exhaustive]
|
||||
|
@ -2,11 +2,7 @@
|
||||
//! for events, rooms, room aliases, room versions, and users.
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![deny(
|
||||
missing_copy_implementations,
|
||||
missing_debug_implementations,
|
||||
//missing_docs
|
||||
)]
|
||||
#![deny(missing_copy_implementations, missing_debug_implementations, missing_docs)]
|
||||
// Since we support Rust 1.36.0, we can't apply this suggestion yet
|
||||
#![allow(clippy::use_self)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
@ -1,5 +1,27 @@
|
||||
/// Declares an item with a doc attribute computed by some macro expression.
|
||||
/// This allows documentation to be dynamically generated based on input.
|
||||
/// Necessary to work around https://github.com/rust-lang/rust/issues/52607.
|
||||
macro_rules! doc_concat {
|
||||
( $( #[doc = $doc:expr] $thing:item )* ) => ( $( #[doc = $doc] $thing )* );
|
||||
}
|
||||
|
||||
macro_rules! common_impls {
|
||||
($id:ident, $try_from:ident, $desc:literal) => {
|
||||
impl<T: ::std::convert::AsRef<str>> $id<T> {
|
||||
doc_concat! {
|
||||
#[doc = concat!("Creates a string slice from this `", stringify!($id), "`")]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.full_id.as_ref()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::std::convert::From<&'a $id<Box<str>>> for $id<&'a str> {
|
||||
fn from(id: &'a $id<Box<str>>) -> Self {
|
||||
id.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::From<$id<Box<str>>> for ::std::string::String {
|
||||
fn from(id: $id<Box<str>>) -> Self {
|
||||
id.full_id.into()
|
||||
|
@ -26,7 +26,15 @@ pub struct RoomAliasId<T> {
|
||||
pub(crate) colon_idx: NonZeroU8,
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> RoomAliasId<T> {
|
||||
impl<T> RoomAliasId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `RoomAliasId`.
|
||||
pub fn as_ref(&self) -> RoomAliasId<&str> {
|
||||
RoomAliasId { full_id: self.full_id.as_ref(), colon_idx: self.colon_idx }
|
||||
}
|
||||
|
||||
/// Returns the room's alias.
|
||||
pub fn alias(&self) -> &str {
|
||||
&self.full_id.as_ref()[1..self.colon_idx.get() as usize]
|
||||
|
@ -26,37 +26,41 @@ pub struct RoomId<T> {
|
||||
pub(crate) colon_idx: NonZeroU8,
|
||||
}
|
||||
|
||||
impl<T> RoomId<T> {
|
||||
impl<T> RoomId<T>
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
/// Attempts to generate a `RoomId` for the given origin server with a localpart consisting of
|
||||
/// 18 random ASCII characters.
|
||||
///
|
||||
/// Fails if the given homeserver cannot be parsed as a valid host.
|
||||
#[cfg(feature = "rand")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
|
||||
pub fn new(server_name: ServerNameRef<'_>) -> Self
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
pub fn new(server_name: ServerNameRef<'_>) -> Self {
|
||||
use crate::generate_localpart;
|
||||
|
||||
let full_id = format!("!{}:{}", generate_localpart(18), server_name).into();
|
||||
|
||||
Self { full_id, colon_idx: NonZeroU8::new(19).unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RoomId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `RoomId`.
|
||||
pub fn as_ref(&self) -> RoomId<&str> {
|
||||
RoomId { full_id: self.full_id.as_ref(), colon_idx: self.colon_idx }
|
||||
}
|
||||
|
||||
/// Returns the rooms's unique ID.
|
||||
pub fn localpart(&self) -> &str
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn localpart(&self) -> &str {
|
||||
&self.full_id.as_ref()[1..self.colon_idx.get() as usize]
|
||||
}
|
||||
|
||||
/// Returns the server name of the room ID.
|
||||
pub fn server_name(&self) -> ServerNameRef<'_>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn server_name(&self) -> ServerNameRef<'_> {
|
||||
ServerNameRef::try_from(&self.full_id.as_ref()[self.colon_idx.get() as usize + 1..])
|
||||
.unwrap()
|
||||
}
|
||||
@ -103,7 +107,7 @@ mod tests {
|
||||
let server_name =
|
||||
ServerNameRef::try_from("example.com").expect("Failed to parse ServerName");
|
||||
let room_id = RoomId::new(server_name);
|
||||
let id_str: &str = room_id.as_ref();
|
||||
let id_str = room_id.as_str();
|
||||
|
||||
assert!(id_str.starts_with('!'));
|
||||
assert_eq!(id_str.len(), 31);
|
||||
|
@ -34,7 +34,15 @@ pub struct RoomIdOrAliasId<T> {
|
||||
colon_idx: NonZeroU8,
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> RoomIdOrAliasId<T> {
|
||||
impl<T> RoomIdOrAliasId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `RoomIdOrAliasId`.
|
||||
pub fn as_ref(&self) -> RoomIdOrAliasId<&str> {
|
||||
RoomIdOrAliasId { full_id: self.full_id.as_ref(), colon_idx: self.colon_idx }
|
||||
}
|
||||
|
||||
/// Returns the local part (everything after the `!` or `#` and before the first colon).
|
||||
pub fn localpart(&self) -> &str {
|
||||
&self.full_id.as_ref()[1..self.colon_idx.get() as usize]
|
||||
|
@ -11,21 +11,23 @@ pub struct ServerKeyId<T> {
|
||||
colon_idx: NonZeroU8,
|
||||
}
|
||||
|
||||
impl<T> ServerKeyId<T> {
|
||||
impl<T> ServerKeyId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `ServerKeyId`.
|
||||
pub fn as_ref(&self) -> ServerKeyId<&str> {
|
||||
ServerKeyId { full_id: self.full_id.as_ref(), colon_idx: self.colon_idx }
|
||||
}
|
||||
|
||||
/// Returns key algorithm of the server key ID.
|
||||
pub fn algorithm(&self) -> ServerKeyAlgorithm
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn algorithm(&self) -> ServerKeyAlgorithm {
|
||||
ServerKeyAlgorithm::from_str(&self.full_id.as_ref()[..self.colon_idx.get() as usize])
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns the version of the server key ID.
|
||||
pub fn version(&self) -> &str
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn version(&self) -> &str {
|
||||
&self.full_id.as_ref()[self.colon_idx.get() as usize + 1..]
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,16 @@ pub struct ServerName<T> {
|
||||
full_id: T,
|
||||
}
|
||||
|
||||
impl<T> ServerName<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `ServerName`.
|
||||
pub fn as_ref(&self) -> ServerName<&str> {
|
||||
ServerName { full_id: self.full_id.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
fn try_from<S, T>(server_name: S) -> Result<ServerName<T>, Error>
|
||||
where
|
||||
S: AsRef<str> + Into<T>,
|
||||
|
@ -32,15 +32,15 @@ pub struct UserId<T> {
|
||||
is_historical: bool,
|
||||
}
|
||||
|
||||
impl<T> UserId<T> {
|
||||
impl<T> UserId<T>
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
/// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
|
||||
/// 12 random ASCII characters.
|
||||
#[cfg(feature = "rand")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
|
||||
pub fn new(server_name: ServerNameRef<'_>) -> Self
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
pub fn new(server_name: ServerNameRef<'_>) -> Self {
|
||||
use crate::generate_localpart;
|
||||
|
||||
let full_id = format!("@{}:{}", generate_localpart(12).to_lowercase(), server_name).into();
|
||||
@ -58,10 +58,7 @@ impl<T> UserId<T> {
|
||||
pub fn parse_with_server_name(
|
||||
id: impl AsRef<str> + Into<T>,
|
||||
server_name: ServerNameRef<'_>,
|
||||
) -> Result<Self, Error>
|
||||
where
|
||||
String: Into<T>,
|
||||
{
|
||||
) -> Result<Self, Error> {
|
||||
let id_str = id.as_ref();
|
||||
|
||||
if id_str.starts_with('@') {
|
||||
@ -76,24 +73,34 @@ impl<T> UserId<T> {
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> UserId<T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// Creates a reference to this `UserId`.
|
||||
pub fn as_ref(&self) -> UserId<&str> {
|
||||
UserId {
|
||||
full_id: self.full_id.as_ref(),
|
||||
colon_idx: self.colon_idx,
|
||||
is_historical: self.is_historical,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the user's localpart.
|
||||
pub fn localpart(&self) -> &str
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn localpart(&self) -> &str {
|
||||
&self.full_id.as_ref()[1..self.colon_idx.get() as usize]
|
||||
}
|
||||
|
||||
/// Returns the server name of the user ID.
|
||||
pub fn server_name(&self) -> ServerNameRef<'_>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn server_name(&self) -> ServerNameRef<'_> {
|
||||
ServerNameRef::try_from(&self.full_id.as_ref()[self.colon_idx.get() as usize + 1..])
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> UserId<T> {
|
||||
/// Whether this user ID is a historical one, i.e. one that doesn't conform to the latest
|
||||
/// specification of the user ID grammar but is still accepted because it was previously
|
||||
/// allowed.
|
||||
@ -232,7 +239,7 @@ mod tests {
|
||||
assert_eq!(user_id.localpart().len(), 12);
|
||||
assert_eq!(user_id.server_name(), "example.com");
|
||||
|
||||
let id_str: &str = user_id.as_ref();
|
||||
let id_str = user_id.as_str();
|
||||
|
||||
assert!(id_str.starts_with('@'));
|
||||
assert_eq!(id_str.len(), 25);
|
||||
|
Loading…
x
Reference in New Issue
Block a user