Further simplify deserialization
This commit is contained in:
parent
d120f77635
commit
32733cf782
@ -7,13 +7,10 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "diesel")]
|
#[cfg(feature = "diesel")]
|
||||||
use diesel::sql_types::Text;
|
use diesel::sql_types::Text;
|
||||||
use serde::{
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
de::{Error as SerdeError, Expected, Unexpected},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
|
||||||
use crate::{display, error::Error, generate_localpart, parse_id};
|
use crate::{deserialize_id, display, error::Error, generate_localpart, parse_id};
|
||||||
|
|
||||||
/// A Matrix event ID.
|
/// A Matrix event ID.
|
||||||
///
|
///
|
||||||
@ -155,10 +152,7 @@ impl<'de> Deserialize<'de> for EventId {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
String::deserialize(deserializer).and_then(|v| {
|
deserialize_id(deserializer, "a Matrix event ID as a string")
|
||||||
EventId::try_from(&v as &str)
|
|
||||||
.map_err(|_| SerdeError::invalid_value(Unexpected::Str(&v), &ExpectedEventId))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,14 +183,6 @@ impl<'a> TryFrom<&'a str> for EventId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectedEventId;
|
|
||||||
|
|
||||||
impl Expected for ExpectedEventId {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a Matrix event ID as a string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
19
src/lib.rs
19
src/lib.rs
@ -14,9 +14,13 @@
|
|||||||
#[cfg_attr(feature = "diesel", macro_use)]
|
#[cfg_attr(feature = "diesel", macro_use)]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
|
|
||||||
use std::fmt::{Formatter, Result as FmtResult};
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
|
fmt::{Formatter, Result as FmtResult},
|
||||||
|
};
|
||||||
|
|
||||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||||
|
use serde::de::{self, Deserialize as _, Deserializer, Unexpected};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub use url::Host;
|
pub use url::Host;
|
||||||
@ -112,3 +116,16 @@ fn parse_id(required_sigil: char, id: &str) -> Result<(&str, Host, u16), Error>
|
|||||||
|
|
||||||
Ok((localpart, host, port))
|
Ok((localpart, host, port))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserializes any type of id using the provided TryFrom implementation.
|
||||||
|
///
|
||||||
|
/// This is a helper function to reduce the boilerplate of the Deserialize implementations.
|
||||||
|
fn deserialize_id<'de, D, T>(deserializer: D, expected_str: &str) -> Result<T, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
T: for<'a> TryFrom<&'a str>,
|
||||||
|
{
|
||||||
|
String::deserialize(deserializer).and_then(|v| {
|
||||||
|
T::try_from(&v).map_err(|_| de::Error::invalid_value(Unexpected::Str(&v), &expected_str))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -7,13 +7,10 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "diesel")]
|
#[cfg(feature = "diesel")]
|
||||||
use diesel::sql_types::Text;
|
use diesel::sql_types::Text;
|
||||||
use serde::{
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
de::{Error as SerdeError, Expected, Unexpected},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
|
||||||
use crate::{display, error::Error, parse_id};
|
use crate::{deserialize_id, display, error::Error, parse_id};
|
||||||
|
|
||||||
/// A Matrix room alias ID.
|
/// A Matrix room alias ID.
|
||||||
///
|
///
|
||||||
@ -80,10 +77,7 @@ impl<'de> Deserialize<'de> for RoomAliasId {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
String::deserialize(deserializer).and_then(|v| {
|
deserialize_id(deserializer, "a Matrix room alias ID as a string")
|
||||||
RoomAliasId::try_from(&v as &str)
|
|
||||||
.map_err(|_| SerdeError::invalid_value(Unexpected::Str(&v), &ExpectedRoomAliasId))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,14 +99,6 @@ impl<'a> TryFrom<&'a str> for RoomAliasId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectedRoomAliasId;
|
|
||||||
|
|
||||||
impl Expected for ExpectedRoomAliasId {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a Matrix room alias ID as a string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -7,13 +7,10 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "diesel")]
|
#[cfg(feature = "diesel")]
|
||||||
use diesel::sql_types::Text;
|
use diesel::sql_types::Text;
|
||||||
use serde::{
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
de::{Error as SerdeError, Expected, Unexpected},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
|
||||||
use crate::{display, error::Error, generate_localpart, parse_id};
|
use crate::{deserialize_id, display, error::Error, generate_localpart, parse_id};
|
||||||
|
|
||||||
/// A Matrix room ID.
|
/// A Matrix room ID.
|
||||||
///
|
///
|
||||||
@ -95,10 +92,7 @@ impl<'de> Deserialize<'de> for RoomId {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
String::deserialize(deserializer).and_then(|v| {
|
deserialize_id(deserializer, "a Matrix room ID as a string")
|
||||||
RoomId::try_from(&v as &str)
|
|
||||||
.map_err(|_| SerdeError::invalid_value(Unexpected::Str(&v), &ExpectedRoomId))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,14 +114,6 @@ impl<'a> TryFrom<&'a str> for RoomId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectedRoomId;
|
|
||||||
|
|
||||||
impl Expected for ExpectedRoomId {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a Matrix room ID as a string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -7,12 +7,11 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "diesel")]
|
#[cfg(feature = "diesel")]
|
||||||
use diesel::sql_types::Text;
|
use diesel::sql_types::Text;
|
||||||
use serde::{
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
de::{Error as SerdeError, Expected, Unexpected},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{display, error::Error, room_alias_id::RoomAliasId, room_id::RoomId, validate_id};
|
use crate::{
|
||||||
|
deserialize_id, display, error::Error, room_alias_id::RoomAliasId, room_id::RoomId, validate_id,
|
||||||
|
};
|
||||||
|
|
||||||
/// A Matrix room ID or a Matrix room alias ID.
|
/// A Matrix room ID or a Matrix room alias ID.
|
||||||
///
|
///
|
||||||
@ -83,11 +82,10 @@ impl<'de> Deserialize<'de> for RoomIdOrAliasId {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
String::deserialize(deserializer).and_then(|v| {
|
deserialize_id(
|
||||||
RoomIdOrAliasId::try_from(&v as &str).map_err(|_| {
|
deserializer,
|
||||||
SerdeError::invalid_value(Unexpected::Str(&v), &ExpectedRoomIdOrAliasId)
|
"a Matrix room ID or room alias ID as a string",
|
||||||
})
|
)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,14 +118,6 @@ impl<'a> TryFrom<&'a str> for RoomIdOrAliasId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectedRoomIdOrAliasId;
|
|
||||||
|
|
||||||
impl Expected for ExpectedRoomIdOrAliasId {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a Matrix room ID or room alias ID as a string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -7,12 +7,9 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "diesel")]
|
#[cfg(feature = "diesel")]
|
||||||
use diesel::sql_types::Text;
|
use diesel::sql_types::Text;
|
||||||
use serde::{
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
de::{Error as SerdeError, Expected, Unexpected},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::{deserialize_id, error::Error};
|
||||||
|
|
||||||
/// Room version identifiers cannot be more than 32 code points.
|
/// Room version identifiers cannot be more than 32 code points.
|
||||||
const MAX_CODE_POINTS: usize = 32;
|
const MAX_CODE_POINTS: usize = 32;
|
||||||
@ -154,10 +151,7 @@ impl<'de> Deserialize<'de> for RoomVersionId {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
String::deserialize(deserializer).and_then(|v| {
|
deserialize_id(deserializer, "a Matrix room version ID as a string")
|
||||||
RoomVersionId::try_from(&v as &str)
|
|
||||||
.map_err(|_| SerdeError::invalid_value(Unexpected::Str(&v), &ExpectedRoomVersionId))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,14 +181,6 @@ impl<'a> TryFrom<&'a str> for RoomVersionId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectedRoomVersionId;
|
|
||||||
|
|
||||||
impl Expected for ExpectedRoomVersionId {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a Matrix room version ID as a string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -7,13 +7,10 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "diesel")]
|
#[cfg(feature = "diesel")]
|
||||||
use diesel::sql_types::Text;
|
use diesel::sql_types::Text;
|
||||||
use serde::{
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
de::{Error as SerdeError, Expected, Unexpected},
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
|
||||||
use crate::{display, error::Error, generate_localpart, parse_id};
|
use crate::{deserialize_id, display, error::Error, generate_localpart, parse_id};
|
||||||
|
|
||||||
/// A Matrix user ID.
|
/// A Matrix user ID.
|
||||||
///
|
///
|
||||||
@ -99,10 +96,7 @@ impl<'de> Deserialize<'de> for UserId {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
String::deserialize(deserializer).and_then(|v| {
|
deserialize_id(deserializer, "a Matrix user ID as a string")
|
||||||
UserId::try_from(&v as &str)
|
|
||||||
.map_err(|_| SerdeError::invalid_value(Unexpected::Str(&v), &ExpectedUserId))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,14 +127,6 @@ impl<'a> TryFrom<&'a str> for UserId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectedUserId;
|
|
||||||
|
|
||||||
impl Expected for ExpectedUserId {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a Matrix user ID as a string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user