Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/17996.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `RoomID` & `EventID` rust types.
166 changes: 166 additions & 0 deletions rust/src/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,34 @@ impl TryFrom<&str> for UserID {
}
}

impl TryFrom<String> for UserID {
type Error = IdentifierError;

/// Will try creating a `UserID` from the provided `&str`.
/// Can fail if the user_id is incorrectly formatted.
fn try_from(s: String) -> Result<Self, Self::Error> {
if !s.starts_with('@') {
return Err(IdentifierError::IncorrectSigil);
}

if s.find(':').is_none() {
return Err(IdentifierError::MissingColon);
}

Ok(UserID(s))
}
}

impl<'de> serde::Deserialize<'de> for UserID {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: String = serde::Deserialize::deserialize(deserializer)?;
UserID::try_from(s).map_err(serde::de::Error::custom)
}
}

impl Deref for UserID {
type Target = str;

Expand All @@ -84,3 +112,141 @@ impl fmt::Display for UserID {
write!(f, "{}", self.0)
}
}

/// A Matrix room_id.
#[derive(Clone, Debug, PartialEq)]
pub struct RoomID(String);

impl RoomID {
/// Returns the `localpart` of the room_id.
pub fn localpart(&self) -> &str {
&self[1..self.colon_pos()]
}

/// Returns the `server_name` / `domain` of the room_id.
pub fn server_name(&self) -> &str {
&self[self.colon_pos() + 1..]
}

/// Returns the position of the ':' inside of the room_id.
/// Used when splitting the room_id into it's respective parts.
fn colon_pos(&self) -> usize {
self.find(':').unwrap()
}
}

impl TryFrom<&str> for RoomID {
type Error = IdentifierError;

/// Will try creating a `RoomID` from the provided `&str`.
/// Can fail if the room_id is incorrectly formatted.
fn try_from(s: &str) -> Result<Self, Self::Error> {
if !s.starts_with('!') {
return Err(IdentifierError::IncorrectSigil);
}

if s.find(':').is_none() {
return Err(IdentifierError::MissingColon);
}

Ok(RoomID(s.to_string()))
}
}

impl TryFrom<String> for RoomID {
type Error = IdentifierError;

/// Will try creating a `RoomID` from the provided `String`.
/// Can fail if the room_id is incorrectly formatted.
fn try_from(s: String) -> Result<Self, Self::Error> {
if !s.starts_with('!') {
return Err(IdentifierError::IncorrectSigil);
}

if s.find(':').is_none() {
return Err(IdentifierError::MissingColon);
}

Ok(RoomID(s))
}
}

impl<'de> serde::Deserialize<'de> for RoomID {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: String = serde::Deserialize::deserialize(deserializer)?;
RoomID::try_from(s).map_err(serde::de::Error::custom)
}
}

impl Deref for RoomID {
type Target = str;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl fmt::Display for RoomID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

/// A Matrix event_id.
#[derive(Clone, Debug, PartialEq)]
pub struct EventID(String);

impl TryFrom<&str> for EventID {
type Error = IdentifierError;

/// Will try creating a `EventID` from the provided `&str`.
/// Can fail if the event_id is incorrectly formatted.
fn try_from(s: &str) -> Result<Self, Self::Error> {
if !s.starts_with('$') {
return Err(IdentifierError::IncorrectSigil);
}

Ok(EventID(s.to_string()))
}
}

impl TryFrom<String> for EventID {
type Error = IdentifierError;

/// Will try creating a `EventID` from the provided `String`.
/// Can fail if the event_id is incorrectly formatted.
fn try_from(s: String) -> Result<Self, Self::Error> {
if !s.starts_with('$') {
return Err(IdentifierError::IncorrectSigil);
}

Ok(EventID(s))
}
}

impl<'de> serde::Deserialize<'de> for EventID {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: String = serde::Deserialize::deserialize(deserializer)?;
EventID::try_from(s).map_err(serde::de::Error::custom)
}
}

impl Deref for EventID {
type Target = str;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl fmt::Display for EventID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
Loading