Skip to main content

Configuration

Struct Configuration 

Source
pub struct Configuration {
    pub owner_member_id: MemberId,
    pub configuration_version: u32,
    pub privacy_mode: PrivacyMode,
    pub display: RoomDisplayMetadata,
    pub max_recent_messages: usize,
    pub max_user_bans: usize,
    pub max_message_size: usize,
    pub max_nickname_size: usize,
    pub max_members: usize,
    pub max_room_name: usize,
    pub max_room_description: usize,
    pub max_direct_messages: Option<usize>,
}

Fields§

§owner_member_id: MemberId§configuration_version: u32§privacy_mode: PrivacyMode§display: RoomDisplayMetadata§max_recent_messages: usize§max_user_bans: usize§max_message_size: usize§max_nickname_size: usize§max_members: usize§max_room_name: usize§max_room_description: usize§max_direct_messages: Option<usize>

Owner-tunable global bound on direct_messages.messages, mirroring how max_recent_messages bounds recent_messages. None means “this configuration was signed before the field existed”; read it through Configuration::effective_max_direct_messages, which substitutes DEFAULT_MAX_DIRECT_MESSAGES, so pre-existing rooms are bounded without the owner having to re-sign anything.

§Why Option + skip_serializing_if, and why that is NOT optional

AuthorizedConfigurationV1::verify_signature re-serializes this whole struct with ciborium and checks the owner’s signature over those bytes. A plain #[serde(default)] usize deserializes old bytes to 0 and then re-serializes them WITH the extra map entry, so the bytes no longer match what the owner signed: every room created before this field existed would fail verify, which also gates the #292 migration PUT — i.e. every existing room bricked, unrecoverably.

Option + skip_serializing_if makes the addition byte-neutral: an old configuration decodes to None, re-encodes without the key, and its signature still verifies. Pinned by legacy_configuration_bytes_still_verify_after_adding_the_field.

Any future field added to Configuration MUST follow this pattern AND be appended LAST — inserting an Option field mid-struct reorders the CBOR map for configurations that set it.

The pattern is one-directional, and deliberately so. It protects OLD bytes read by NEW code. The reverse — an old-struct client reading a configuration that actually SETS this field — still breaks: serde has no deny_unknown_fields here, so such a client silently drops the key, re-serializes one entry short, and the owner signature fails. That is unreachable only because the contract key is BLAKE3(wasm, params) and both the UI and riverctl include_bytes! the WASM they derive the key from: a client with the old struct also derives the OLD contract key and never sees state carrying this field. Do not weaken that coupling.

Implementations§

Source§

impl Configuration

Source

pub fn effective_max_direct_messages(&self) -> usize

The global DM cap in force for this room: the owner’s explicit Self::max_direct_messages, or DEFAULT_MAX_DIRECT_MESSAGES when unset. Every retention and horizon decision MUST read the cap through here so a legacy (None) configuration and an explicitly-defaulted one behave identically.

Trait Implementations§

Source§

impl Clone for Configuration

Source§

fn clone(&self) -> Configuration

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Configuration

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Configuration

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Configuration

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Configuration

Source§

fn eq(&self, other: &Configuration) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Configuration

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Configuration

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.