Skip to content
This repository was archived by the owner on Aug 15, 2025. It is now read-only.

Commit 51faac9

Browse files
committed
feat: Add type LocalName
1 parent c258b91 commit 51faac9

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use regex::Regex;
2+
3+
use crate::types::local_name::{LocalName, REGEX_LOCAL_NAME};
4+
5+
impl super::Constrained for LocalName {
6+
fn validate(
7+
&self,
8+
_target: Option<crate::certs::Target>,
9+
) -> Result<(), crate::errors::ConstraintError> {
10+
#[allow(clippy::expect_used)]
11+
let regex = Regex::new(REGEX_LOCAL_NAME).expect("This Regex must never be invalid.");
12+
if regex.is_match(&self.0) {
13+
Ok(())
14+
} else {
15+
Err(super::ConstraintError::Malformed(Some(format!(
16+
"{} is not of allowed regex {REGEX_LOCAL_NAME}",
17+
self.0
18+
))))
19+
}
20+
}
21+
}

src/constraints/types/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

55
mod federation_id;
6+
mod local_name;
67
mod rawr;
78
mod service;
89

src/types/local_name.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use std::str::FromStr;
2+
3+
use crate::Constrained;
4+
use crate::errors::ConstraintError;
5+
6+
/// Rust-flavor regular expression describing valid format for the local name of a Federation ID.
7+
pub const REGEX_LOCAL_NAME: &str = r#"\b([a-z0-9._%+-]+)$"#;
8+
9+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10+
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
11+
/// A polyproto "Local Name"[(1)](https://polyproto.org/docs/protocols/core/#5-federation-ids-fids)[(2)](https://polyproto.org/docs/protocols/core/#6111-polyproto-distinguished-name-pdn)
12+
/// is the instance-unique actor handle before the `@` in a [FederationId](crate::types::FederationId).
13+
///
14+
/// ## Example
15+
///
16+
/// In a `FederationId` of `[email protected]`, the local name would be `xenia`.
17+
pub struct LocalName(pub(crate) String);
18+
19+
impl LocalName {
20+
/// Creates [Self], ensuring that `name` is a valid, acceptable `LocalName`.
21+
pub fn new(name: &str) -> Result<Self, ConstraintError> {
22+
let local_name = LocalName(name.to_owned());
23+
local_name.validate(None)?;
24+
Ok(local_name)
25+
}
26+
}
27+
28+
impl FromStr for LocalName {
29+
type Err = ConstraintError;
30+
31+
fn from_str(s: &str) -> Result<Self, Self::Err> {
32+
LocalName::new(s)
33+
}
34+
}

src/types/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub mod encrypted_pkm;
1212
/// Module defining the [FederationId] type.
1313
#[cfg(feature = "types")]
1414
pub mod federation_id;
15+
/// Module defining the [LocalName] type.
16+
pub mod local_name;
1517
/// Module defining the [PolyprotoDistinguishedName] type.
1618
pub mod pdn;
1719

0 commit comments

Comments
 (0)