identifiers: Generate public parse
functions for opaque ID types with invariants
This commit is contained in:
parent
87194d5bf9
commit
6324034f03
@ -201,6 +201,24 @@ macro_rules! opaque_identifier {
|
||||
|
||||
macro_rules! opaque_identifier_validated {
|
||||
($id:ident, $validate_id:expr) => {
|
||||
impl $id {
|
||||
#[rustfmt::skip]
|
||||
doc_concat! {
|
||||
#[doc = concat!("\
|
||||
Try parsing a `&str` into a `Box<", stringify!($id), ">`.\n\
|
||||
\n\
|
||||
The same can also be done using `FromStr`, `TryFrom` or `TryInto`.\n\
|
||||
This function is simply more constrained and thus useful in generic contexts.\
|
||||
")]
|
||||
pub fn parse(
|
||||
s: impl AsRef<str> + Into<Box<str>>,
|
||||
) -> Result<Box<Self>, crate::Error> {
|
||||
$validate_id(s.as_ref())?;
|
||||
Ok($id::from_owned(s.into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opaque_identifier_common_impls!($id);
|
||||
|
||||
impl From<Box<$id>> for String {
|
||||
@ -219,21 +237,13 @@ macro_rules! opaque_identifier_validated {
|
||||
|
||||
let s = String::deserialize(deserializer)?;
|
||||
|
||||
match try_from(s) {
|
||||
match $id::parse(s) {
|
||||
Ok(o) => Ok(o),
|
||||
Err(e) => Err(D::Error::custom(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn try_from<S>(s: S) -> Result<Box<$id>, crate::Error>
|
||||
where
|
||||
S: AsRef<str> + Into<Box<str>>,
|
||||
{
|
||||
$validate_id(s.as_ref())?;
|
||||
Ok($id::from_owned(s.into()))
|
||||
}
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a str> for &'a $id {
|
||||
type Error = crate::Error;
|
||||
|
||||
@ -247,7 +257,7 @@ macro_rules! opaque_identifier_validated {
|
||||
type Err = crate::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
try_from(s)
|
||||
$id::parse(s)
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +265,7 @@ macro_rules! opaque_identifier_validated {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||
try_from(s)
|
||||
$id::parse(s)
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +273,7 @@ macro_rules! opaque_identifier_validated {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||
try_from(s)
|
||||
$id::parse(s)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -45,7 +45,7 @@ impl UserId {
|
||||
let id_str = id.as_ref();
|
||||
|
||||
if id_str.starts_with('@') {
|
||||
try_from(id)
|
||||
Self::parse(id)
|
||||
} else {
|
||||
Ok(Self::from_owned(format!("@{}:{}", id_str, server_name).into()))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user