pub struct GroupId(/* private fields */);Expand description
Unique identifier for an MLS group.
Group ids flow from the wire into MlsStorage as raw key_id storage
keys, so they are validated at construction: one or more non-empty
colon-separated segments (: is the namespace separator used by
session:<a>:<b> and group:<uuid> ids), each segment subject to the
same storage-key policy as UserId/AppId (no path-traversal components,
control characters, /, or \), with a total length cap of
GroupId::MAX_LEN.
Implementations§
Source§impl GroupId
impl GroupId
Sourcepub const MAX_LEN: usize = MAX_STRING_FIELD_LEN
pub const MAX_LEN: usize = MAX_STRING_FIELD_LEN
Maximum accepted group id length in bytes.
This is the compact wire format’s string-field cap, not a copy of it: a group id that could not survive a round trip through the envelope must not be constructible in the first place.
Sourcepub fn new(id: impl Into<String>) -> Result<Self>
pub fn new(id: impl Into<String>) -> Result<Self>
Creates a new group ID, rejecting storage-hostile values.
Sourcepub fn for_session(user_a: &str, user_b: &str) -> Result<Self>
pub fn for_session(user_a: &str, user_b: &str) -> Result<Self>
Builds the deterministic group ID for a 1:1 session, rejecting storage-hostile user ids (the id becomes a raw storage key).
Both peers must land on the same string, so the two ids are put in a
canonical order. When both are addresses that order is
Address order, the underlying hash
bytes, because the bech32 charset is not ASCII-monotonic (value 4
renders as y 0x79, value 5 as 9 0x39), so sorting the rendered
strings would disagree with every other address comparison in the
protocol. Ids that are not both addresses fall back to string order,
which is all a nickname id has.
Either way the result is symmetric in its arguments, which is the property peers actually depend on.