//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `vtc/rooms/community/create`. Version: `0.2`.
#[allow(unused_imports)]
use serde::{Deserialize, Serialize};
/// Error types.
pub mod error {
/// Error from a `TryFrom` or `FromStr` implementation.
pub struct ConversionError(::std::borrow::Cow<'static, str>);
impl ::std::error::Error for ConversionError {}
impl ::std::fmt::Display for ConversionError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> {
::std::fmt::Display::fmt(&self.0, f)
}
}
impl ::std::fmt::Debug for ConversionError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> {
::std::fmt::Debug::fmt(&self.0, f)
}
}
impl From<&'static str> for ConversionError {
fn from(value: &'static str) -> Self {
Self(value.into())
}
}
impl From<String> for ConversionError {
fn from(value: String) -> Self {
Self(value.into())
}
}
}
///What vtc/rooms/community/{create,get,list}/0.2 and vtc/rooms/community/update/0.1 return: `CommunityRoom` plus the details an administrator keeps track of a room by — `description`, `tags`, and who last changed them and when. A separate definition, not a change to `CommunityRoom`, so that the 0.1 versions of those tasks keep the exact shape they published. The room's creation is `room.createdAt` and `createdBy`.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "CommunityRoomV2",
/// "description": "What vtc/rooms/community/{create,get,list}/0.2 and vtc/rooms/community/update/0.1 return: `CommunityRoom` plus the details an administrator keeps track of a room by — `description`, `tags`, and who last changed them and when. A separate definition, not a change to `CommunityRoom`, so that the 0.1 versions of those tasks keep the exact shape they published. The room's creation is `room.createdAt` and `createdBy`.",
/// "type": "object",
/// "required": [
/// "admitted",
/// "label",
/// "offered",
/// "room"
/// ],
/// "properties": {
/// "admitted": {
/// "description": "Members in state `admitted`.",
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "createdBy": {
/// "description": "The administrator who created it.",
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
/// },
/// "description": {
/// "description": "Absent when the room has none.",
/// "$ref": "#/definitions/RoomDescription"
/// },
/// "detailsUpdatedAt": {
/// "description": "When `label`, `description` or `tags` last changed. Absent until the first change after creation. Distinct from `room.updatedAt`, which is the host record's and moves with the room's epoch and lifecycle.",
/// "type": "string",
/// "format": "date-time"
/// },
/// "detailsUpdatedBy": {
/// "description": "The administrator who made that change. Present exactly when `detailsUpdatedAt` is. The earlier values and who set them are in the community's audit trail, not here.",
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
/// },
/// "label": {
/// "$ref": "#/definitions/RoomLabel"
/// },
/// "offered": {
/// "description": "Offers not yet accepted or withdrawn.",
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "ownerAuthorityValidUntil": {
/// "description": "When the community's own `admin` authority over the room expires. A room whose owner's authority lapses can no longer advance its epoch, admit or remove; a community SHOULD renew it well before.",
/// "type": "string",
/// "format": "date-time"
/// },
/// "room": {
/// "$ref": "#/definitions/HostedRoom"
/// },
/// "storageConfig": {
/// "description": "The storage config receiving the room's new uploads.",
/// "$ref": "#/definitions/StorageConfigId"
/// },
/// "tags": {
/// "description": "Absent or empty when the room has none.",
/// "$ref": "#/definitions/RoomTags"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct CommunityRoomV2 {
///Members in state `admitted`.
pub admitted: u64,
///The administrator who created it.
#[serde(
rename = "createdBy",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub created_by: ::std::option::Option<CommunityRoomV2CreatedBy>,
///Absent when the room has none.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub description: ::std::option::Option<RoomDescription>,
///When `label`, `description` or `tags` last changed. Absent until the first change after creation. Distinct from `room.updatedAt`, which is the host record's and moves with the room's epoch and lifecycle.
#[serde(
rename = "detailsUpdatedAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub details_updated_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
///The administrator who made that change. Present exactly when `detailsUpdatedAt` is. The earlier values and who set them are in the community's audit trail, not here.
#[serde(
rename = "detailsUpdatedBy",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub details_updated_by: ::std::option::Option<CommunityRoomV2DetailsUpdatedBy>,
pub label: RoomLabel,
///Offers not yet accepted or withdrawn.
pub offered: u64,
///When the community's own `admin` authority over the room expires. A room whose owner's authority lapses can no longer advance its epoch, admit or remove; a community SHOULD renew it well before.
#[serde(
rename = "ownerAuthorityValidUntil",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub owner_authority_valid_until:
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
pub room: HostedRoom,
///The storage config receiving the room's new uploads.
#[serde(
rename = "storageConfig",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub storage_config: ::std::option::Option<StorageConfigId>,
///Absent or empty when the room has none.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub tags: ::std::option::Option<RoomTags>,
}
impl CommunityRoomV2 {
pub fn builder() -> builder::CommunityRoomV2 {
Default::default()
}
}
///The administrator who created it.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The administrator who created it.",
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct CommunityRoomV2CreatedBy(::std::string::String);
impl ::std::ops::Deref for CommunityRoomV2CreatedBy {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<CommunityRoomV2CreatedBy> for ::std::string::String {
fn from(value: CommunityRoomV2CreatedBy) -> Self {
value.0
}
}
impl ::std::str::FromStr for CommunityRoomV2CreatedBy {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 2048usize {
return Err("longer than 2048 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^did:").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^did:\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for CommunityRoomV2CreatedBy {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for CommunityRoomV2CreatedBy {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for CommunityRoomV2CreatedBy {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for CommunityRoomV2CreatedBy {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///The administrator who made that change. Present exactly when `detailsUpdatedAt` is. The earlier values and who set them are in the community's audit trail, not here.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The administrator who made that change. Present exactly when `detailsUpdatedAt` is. The earlier values and who set them are in the community's audit trail, not here.",
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct CommunityRoomV2DetailsUpdatedBy(::std::string::String);
impl ::std::ops::Deref for CommunityRoomV2DetailsUpdatedBy {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<CommunityRoomV2DetailsUpdatedBy> for ::std::string::String {
fn from(value: CommunityRoomV2DetailsUpdatedBy) -> Self {
value.0
}
}
impl ::std::str::FromStr for CommunityRoomV2DetailsUpdatedBy {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 2048usize {
return Err("longer than 2048 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^did:").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^did:\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for CommunityRoomV2DetailsUpdatedBy {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for CommunityRoomV2DetailsUpdatedBy {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for CommunityRoomV2DetailsUpdatedBy {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for CommunityRoomV2DetailsUpdatedBy {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Ext",
/// "description": "Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.",
/// "type": "object",
/// "minProperties": 1,
/// "additionalProperties": true,
/// "propertyNames": {
/// "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
/// }
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct Ext(pub ::std::collections::HashMap<ExtKey, ::serde_json::Value>);
impl ::std::ops::Deref for Ext {
type Target = ::std::collections::HashMap<ExtKey, ::serde_json::Value>;
fn deref(&self) -> &::std::collections::HashMap<ExtKey, ::serde_json::Value> {
&self.0
}
}
impl ::std::convert::From<Ext> for ::std::collections::HashMap<ExtKey, ::serde_json::Value> {
fn from(value: Ext) -> Self {
value.0
}
}
impl ::std::convert::From<::std::collections::HashMap<ExtKey, ::serde_json::Value>> for Ext {
fn from(value: ::std::collections::HashMap<ExtKey, ::serde_json::Value>) -> Self {
Self(value)
}
}
///`ExtKey`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ExtKey(::std::string::String);
impl ::std::ops::Deref for ExtKey {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ExtKey> for ::std::string::String {
fn from(value: ExtKey) -> Self {
value.0
}
}
impl ::std::str::FromStr for ExtKey {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for ExtKey {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///One room, as its host holds it — member for member the `HostedRoom` of vtc/rooms/list/0.1, which defines it inside its own payload schema. Nothing derived from the room's contents, and no member list: the host has none.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "HostedRoom",
/// "description": "One room, as its host holds it — member for member the `HostedRoom` of vtc/rooms/list/0.1, which defines it inside its own payload schema. Nothing derived from the room's contents, and no member list: the host has none.",
/// "type": "object",
/// "required": [
/// "createdAt",
/// "epoch",
/// "lifecycle",
/// "ownerDid",
/// "retentionDays",
/// "retentionPolicy",
/// "roomId",
/// "updatedAt",
/// "visibility"
/// ],
/// "properties": {
/// "createdAt": {
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "epoch": {
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "epochExpiresAt": {
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "lifecycle": {
/// "type": "string",
/// "enum": [
/// "live",
/// "lapsed",
/// "dormant",
/// "reclaimable"
/// ]
/// },
/// "mirrorOf": {
/// "type": "string",
/// "maxLength": 2048,
/// "minLength": 1
/// },
/// "ownerDid": {
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
/// },
/// "retentionDays": {
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "retentionPolicy": {
/// "$ref": "#/definitions/RetentionPolicy"
/// },
/// "roomId": {
/// "type": "string",
/// "maxLength": 512,
/// "minLength": 1
/// },
/// "updatedAt": {
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "visibility": {
/// "$ref": "#/definitions/Visibility"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct HostedRoom {
#[serde(rename = "createdAt")]
pub created_at: u64,
pub epoch: u64,
#[serde(
rename = "epochExpiresAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub epoch_expires_at: ::std::option::Option<u64>,
pub lifecycle: HostedRoomLifecycle,
#[serde(
rename = "mirrorOf",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub mirror_of: ::std::option::Option<HostedRoomMirrorOf>,
#[serde(rename = "ownerDid")]
pub owner_did: HostedRoomOwnerDid,
#[serde(rename = "retentionDays")]
pub retention_days: u64,
#[serde(rename = "retentionPolicy")]
pub retention_policy: RetentionPolicy,
#[serde(rename = "roomId")]
pub room_id: HostedRoomRoomId,
#[serde(rename = "updatedAt")]
pub updated_at: u64,
pub visibility: Visibility,
}
impl HostedRoom {
pub fn builder() -> builder::HostedRoom {
Default::default()
}
}
///`HostedRoomLifecycle`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "enum": [
/// "live",
/// "lapsed",
/// "dormant",
/// "reclaimable"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum HostedRoomLifecycle {
#[serde(rename = "live")]
Live,
#[serde(rename = "lapsed")]
Lapsed,
#[serde(rename = "dormant")]
Dormant,
#[serde(rename = "reclaimable")]
Reclaimable,
}
impl ::std::fmt::Display for HostedRoomLifecycle {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Live => f.write_str("live"),
Self::Lapsed => f.write_str("lapsed"),
Self::Dormant => f.write_str("dormant"),
Self::Reclaimable => f.write_str("reclaimable"),
}
}
}
impl ::std::str::FromStr for HostedRoomLifecycle {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"live" => Ok(Self::Live),
"lapsed" => Ok(Self::Lapsed),
"dormant" => Ok(Self::Dormant),
"reclaimable" => Ok(Self::Reclaimable),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for HostedRoomLifecycle {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for HostedRoomLifecycle {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for HostedRoomLifecycle {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///`HostedRoomMirrorOf`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "maxLength": 2048,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct HostedRoomMirrorOf(::std::string::String);
impl ::std::ops::Deref for HostedRoomMirrorOf {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<HostedRoomMirrorOf> for ::std::string::String {
fn from(value: HostedRoomMirrorOf) -> Self {
value.0
}
}
impl ::std::str::FromStr for HostedRoomMirrorOf {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 2048usize {
return Err("longer than 2048 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for HostedRoomMirrorOf {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for HostedRoomMirrorOf {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for HostedRoomMirrorOf {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for HostedRoomMirrorOf {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`HostedRoomOwnerDid`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct HostedRoomOwnerDid(::std::string::String);
impl ::std::ops::Deref for HostedRoomOwnerDid {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<HostedRoomOwnerDid> for ::std::string::String {
fn from(value: HostedRoomOwnerDid) -> Self {
value.0
}
}
impl ::std::str::FromStr for HostedRoomOwnerDid {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 2048usize {
return Err("longer than 2048 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^did:").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^did:\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for HostedRoomOwnerDid {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for HostedRoomOwnerDid {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for HostedRoomOwnerDid {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for HostedRoomOwnerDid {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`HostedRoomRoomId`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "maxLength": 512,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct HostedRoomRoomId(::std::string::String);
impl ::std::ops::Deref for HostedRoomRoomId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<HostedRoomRoomId> for ::std::string::String {
fn from(value: HostedRoomRoomId) -> Self {
value.0
}
}
impl ::std::str::FromStr for HostedRoomRoomId {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 512usize {
return Err("longer than 512 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for HostedRoomRoomId {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for HostedRoomRoomId {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for HostedRoomRoomId {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for HostedRoomRoomId {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`Payload`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "$id": "https://trusttasks.org/spec/vtc/rooms/community/create/0.2",
/// "title": "Payload",
/// "type": "object",
/// "required": [
/// "label",
/// "reason",
/// "visibility"
/// ],
/// "properties": {
/// "description": {
/// "description": "What the room is for, shown beside its label. Absent: the room has none until an administrator gives it one with vtc/rooms/community/update.",
/// "$ref": "#/definitions/RoomDescription"
/// },
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "label": {
/// "$ref": "#/definitions/RoomLabel"
/// },
/// "reason": {
/// "$ref": "#/definitions/Reason"
/// },
/// "retentionDays": {
/// "description": "How long the room is kept after it lapses. Absent: the community's default.",
/// "type": "integer",
/// "maximum": 36500.0,
/// "minimum": 1.0
/// },
/// "retentionPolicy": {
/// "description": "Whether the room keeps its history readable across a membership change. Immutable; absent means `chained`.",
/// "$ref": "#/definitions/RetentionPolicy"
/// },
/// "storageConfig": {
/// "description": "The storage config to receive the room's uploads. Absent: what the community's rooms policy decides, else its default config.",
/// "$ref": "#/definitions/StorageConfigId"
/// },
/// "tags": {
/// "description": "Tags to file the room under, for administrators' filtering. Absent: none.",
/// "$ref": "#/definitions/RoomTags"
/// },
/// "visibility": {
/// "description": "The tier, fixed for the life of the room. The community's rooms policy decides which it may create.",
/// "$ref": "#/definitions/Visibility"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
///What the room is for, shown beside its label. Absent: the room has none until an administrator gives it one with vtc/rooms/community/update.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub description: ::std::option::Option<RoomDescription>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
pub label: RoomLabel,
pub reason: Reason,
///How long the room is kept after it lapses. Absent: the community's default.
#[serde(
rename = "retentionDays",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub retention_days: ::std::option::Option<::std::num::NonZeroU64>,
///Whether the room keeps its history readable across a membership change. Immutable; absent means `chained`.
#[serde(
rename = "retentionPolicy",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub retention_policy: ::std::option::Option<RetentionPolicy>,
///The storage config to receive the room's uploads. Absent: what the community's rooms policy decides, else its default config.
#[serde(
rename = "storageConfig",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub storage_config: ::std::option::Option<StorageConfigId>,
///Tags to file the room under, for administrators' filtering. Absent: none.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub tags: ::std::option::Option<RoomTags>,
///The tier, fixed for the life of the room. The community's rooms policy decides which it may create.
pub visibility: Visibility,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///Why the administrator is making this change. Recorded with it in the audit trail. Attributed to its author on every surface and untrusted: it MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Reason",
/// "description": "Why the administrator is making this change. Recorded with it in the audit trail. Attributed to its author on every surface and untrusted: it MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.",
/// "type": "string",
/// "maxLength": 500,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct Reason(::std::string::String);
impl ::std::ops::Deref for Reason {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<Reason> for ::std::string::String {
fn from(value: Reason) -> Self {
value.0
}
}
impl ::std::str::FromStr for Reason {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 500usize {
return Err("longer than 500 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for Reason {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for Reason {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for Reason {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for Reason {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Success response to vtc/rooms/community/create. Type https://trusttasks.org/spec/vtc/rooms/community/create/0.2#response. The room as created, owned by the community.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Response",
/// "description": "Success response to vtc/rooms/community/create. Type https://trusttasks.org/spec/vtc/rooms/community/create/0.2#response. The room as created, owned by the community.",
/// "type": "object",
/// "required": [
/// "room"
/// ],
/// "properties": {
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "room": {
/// "$ref": "#/definitions/CommunityRoomV2"
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "response"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Response {
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
pub room: CommunityRoomV2,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
///Whether a room keeps its history readable across a membership change, fixed at creation and immutable thereafter — like `Visibility`, and for the same reason: the rungs of an epoch key chain either exist for an epoch or they do not, and no later change of mind can seal key material that was never sealed or unseal what was already severed. `chained`: each advance produces an `EpochLink`, so every member reads the room's whole retained history however long they have been in it — what a **library** wants, at the cost of post-compromise security for record content, since a compromised current key then reaches every retained epoch. `fromJoin`: no rungs are produced, so a member reads only from the epoch their group state is at — what a **stream** wants, and what a room under a strict forward-secrecy obligation wants, at the cost that a joining member finds an empty-looking room and nobody can reread a record once their group state has moved past the epoch it was sealed under. Absent means `chained`; see the prose on why the absent case is the readable one.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "RetentionPolicy",
/// "description": "Whether a room keeps its history readable across a membership change, fixed at creation and immutable thereafter — like `Visibility`, and for the same reason: the rungs of an epoch key chain either exist for an epoch or they do not, and no later change of mind can seal key material that was never sealed or unseal what was already severed. `chained`: each advance produces an `EpochLink`, so every member reads the room's whole retained history however long they have been in it — what a **library** wants, at the cost of post-compromise security for record content, since a compromised current key then reaches every retained epoch. `fromJoin`: no rungs are produced, so a member reads only from the epoch their group state is at — what a **stream** wants, and what a room under a strict forward-secrecy obligation wants, at the cost that a joining member finds an empty-looking room and nobody can reread a record once their group state has moved past the epoch it was sealed under. Absent means `chained`; see the prose on why the absent case is the readable one.",
/// "type": "string",
/// "enum": [
/// "chained",
/// "fromJoin"
/// ],
/// "$comment": "Deliberately no JSON Schema `default`. A declared default is materialised by the generated bindings — the member becomes non-optional with a serde default — so an absent value would reappear as an explicit one on re-serialisation and break round-trip idempotence for every document written before this member existed. The meaning of absence is stated in prose, where a binding cannot act on it."
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum RetentionPolicy {
#[serde(rename = "chained")]
Chained,
#[serde(rename = "fromJoin")]
FromJoin,
}
impl ::std::fmt::Display for RetentionPolicy {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Chained => f.write_str("chained"),
Self::FromJoin => f.write_str("fromJoin"),
}
}
}
impl ::std::str::FromStr for RetentionPolicy {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"chained" => Ok(Self::Chained),
"fromJoin" => Ok(Self::FromJoin),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for RetentionPolicy {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for RetentionPolicy {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for RetentionPolicy {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///What the room is for, in a sentence or a short paragraph, written by an administrator: shown to administrators holding `vtc.rooms.manage` and to the members the room is offered to. Plain text — a consumer renders it as text, never as markup. Like `RoomLabel`, it is the community's own record as the room's owner: not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `description` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. It MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "RoomDescription",
/// "description": "What the room is for, in a sentence or a short paragraph, written by an administrator: shown to administrators holding `vtc.rooms.manage` and to the members the room is offered to. Plain text — a consumer renders it as text, never as markup. Like `RoomLabel`, it is the community's own record as the room's owner: not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `description` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. It MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.",
/// "type": "string",
/// "maxLength": 1000,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct RoomDescription(::std::string::String);
impl ::std::ops::Deref for RoomDescription {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<RoomDescription> for ::std::string::String {
fn from(value: RoomDescription) -> Self {
value.0
}
}
impl ::std::str::FromStr for RoomDescription {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 1000usize {
return Err("longer than 1000 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for RoomDescription {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for RoomDescription {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for RoomDescription {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for RoomDescription {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///A name for the room, chosen by an administrator: shown to administrators and to the members a room is offered to. Not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `name` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. MUST NOT carry personal data.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "RoomLabel",
/// "description": "A name for the room, chosen by an administrator: shown to administrators and to the members a room is offered to. Not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `name` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. MUST NOT carry personal data.",
/// "type": "string",
/// "maxLength": 128,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct RoomLabel(::std::string::String);
impl ::std::ops::Deref for RoomLabel {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<RoomLabel> for ::std::string::String {
fn from(value: RoomLabel) -> Self {
value.0
}
}
impl ::std::str::FromStr for RoomLabel {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 128usize {
return Err("longer than 128 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for RoomLabel {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for RoomLabel {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for RoomLabel {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for RoomLabel {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///A short identifier an administrator files a community-owned room under — `board`, `working-group`, `finance` — so the room list can be filtered. Lower-case letters, digits and hyphens, starting with a letter or digit. Owner-side tracking metadata for holders of `vtc.rooms.manage` only: never shown to members, never sent on the room's host path, and it confers nothing.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "RoomTag",
/// "description": "A short identifier an administrator files a community-owned room under — `board`, `working-group`, `finance` — so the room list can be filtered. Lower-case letters, digits and hyphens, starting with a letter or digit. Owner-side tracking metadata for holders of `vtc.rooms.manage` only: never shown to members, never sent on the room's host path, and it confers nothing.",
/// "type": "string",
/// "maxLength": 32,
/// "minLength": 1,
/// "pattern": "^[a-z0-9][a-z0-9-]{0,31}$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct RoomTag(::std::string::String);
impl ::std::ops::Deref for RoomTag {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<RoomTag> for ::std::string::String {
fn from(value: RoomTag) -> Self {
value.0
}
}
impl ::std::str::FromStr for RoomTag {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 32usize {
return Err("longer than 32 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[a-z0-9][a-z0-9-]{0,31}$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[a-z0-9][a-z0-9-]{0,31}$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for RoomTag {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for RoomTag {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for RoomTag {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for RoomTag {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///The room's tags, at most eight, as a set: order carries no meaning. An empty list means the room has none — a tag grants nothing, so empty has no more dangerous reading.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "RoomTags",
/// "description": "The room's tags, at most eight, as a set: order carries no meaning. An empty list means the room has none — a tag grants nothing, so empty has no more dangerous reading.",
/// "type": "array",
/// "items": {
/// "$ref": "#/definitions/RoomTag"
/// },
/// "maxItems": 8,
/// "uniqueItems": true
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct RoomTags(pub Vec<RoomTag>);
impl ::std::ops::Deref for RoomTags {
type Target = Vec<RoomTag>;
fn deref(&self) -> &Vec<RoomTag> {
&self.0
}
}
impl ::std::convert::From<RoomTags> for Vec<RoomTag> {
fn from(value: RoomTags) -> Self {
value.0
}
}
impl ::std::convert::From<Vec<RoomTag>> for RoomTags {
fn from(value: Vec<RoomTag>) -> Self {
Self(value)
}
}
///A storage config's identifier, chosen by the administrator who creates it and immutable thereafter: lowercase letters, digits and inner hyphens, at most 64 characters (`eu-s3-primary`, `walrus-main`). Unique within the community. Never reused after a config is retired, because blobs name their config by this value.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "StorageConfigId",
/// "description": "A storage config's identifier, chosen by the administrator who creates it and immutable thereafter: lowercase letters, digits and inner hyphens, at most 64 characters (`eu-s3-primary`, `walrus-main`). Unique within the community. Never reused after a config is retired, because blobs name their config by this value.",
/// "type": "string",
/// "maxLength": 64,
/// "minLength": 1,
/// "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct StorageConfigId(::std::string::String);
impl ::std::ops::Deref for StorageConfigId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<StorageConfigId> for ::std::string::String {
fn from(value: StorageConfigId) -> Self {
value.0
}
}
impl ::std::str::FromStr for StorageConfigId {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 64usize {
return Err("longer than 64 characters".into());
}
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for StorageConfigId {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for StorageConfigId {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for StorageConfigId {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for StorageConfigId {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///How much of a room its host can see, fixed at creation and immutable thereafter. `open`: records are cleartext, searchable and fully audited. `attributed`: record content is sealed, and the host still learns which member acted. `private`: content is sealed and membership is presented in zero knowledge, so the host verifies that a member acted without learning which. Immutable because a downgrade cannot un-see cleartext and an upgrade would protect only what came after while presenting as though it protected everything.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Visibility",
/// "description": "How much of a room its host can see, fixed at creation and immutable thereafter. `open`: records are cleartext, searchable and fully audited. `attributed`: record content is sealed, and the host still learns which member acted. `private`: content is sealed and membership is presented in zero knowledge, so the host verifies that a member acted without learning which. Immutable because a downgrade cannot un-see cleartext and an upgrade would protect only what came after while presenting as though it protected everything.",
/// "type": "string",
/// "enum": [
/// "open",
/// "attributed",
/// "private"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum Visibility {
#[serde(rename = "open")]
Open,
#[serde(rename = "attributed")]
Attributed,
#[serde(rename = "private")]
Private,
}
impl ::std::fmt::Display for Visibility {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Open => f.write_str("open"),
Self::Attributed => f.write_str("attributed"),
Self::Private => f.write_str("private"),
}
}
}
impl ::std::str::FromStr for Visibility {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"open" => Ok(Self::Open),
"attributed" => Ok(Self::Attributed),
"private" => Ok(Self::Private),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for Visibility {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for Visibility {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for Visibility {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
/// Types for composing complex structures.
pub mod builder {
#[derive(Clone, Debug)]
pub struct CommunityRoomV2 {
admitted: ::std::result::Result<u64, ::std::string::String>,
created_by: ::std::result::Result<
::std::option::Option<super::CommunityRoomV2CreatedBy>,
::std::string::String,
>,
description: ::std::result::Result<
::std::option::Option<super::RoomDescription>,
::std::string::String,
>,
details_updated_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
details_updated_by: ::std::result::Result<
::std::option::Option<super::CommunityRoomV2DetailsUpdatedBy>,
::std::string::String,
>,
label: ::std::result::Result<super::RoomLabel, ::std::string::String>,
offered: ::std::result::Result<u64, ::std::string::String>,
owner_authority_valid_until: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
room: ::std::result::Result<super::HostedRoom, ::std::string::String>,
storage_config: ::std::result::Result<
::std::option::Option<super::StorageConfigId>,
::std::string::String,
>,
tags: ::std::result::Result<::std::option::Option<super::RoomTags>, ::std::string::String>,
}
impl ::std::default::Default for CommunityRoomV2 {
fn default() -> Self {
Self {
admitted: Err("no value supplied for admitted".to_string()),
created_by: Ok(Default::default()),
description: Ok(Default::default()),
details_updated_at: Ok(Default::default()),
details_updated_by: Ok(Default::default()),
label: Err("no value supplied for label".to_string()),
offered: Err("no value supplied for offered".to_string()),
owner_authority_valid_until: Ok(Default::default()),
room: Err("no value supplied for room".to_string()),
storage_config: Ok(Default::default()),
tags: Ok(Default::default()),
}
}
}
impl CommunityRoomV2 {
pub fn admitted<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.admitted = value
.try_into()
.map_err(|e| format!("error converting supplied value for admitted: {e}"));
self
}
pub fn created_by<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::CommunityRoomV2CreatedBy>>,
T::Error: ::std::fmt::Display,
{
self.created_by = value
.try_into()
.map_err(|e| format!("error converting supplied value for created_by: {e}"));
self
}
pub fn description<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::RoomDescription>>,
T::Error: ::std::fmt::Display,
{
self.description = value
.try_into()
.map_err(|e| format!("error converting supplied value for description: {e}"));
self
}
pub fn details_updated_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
>,
T::Error: ::std::fmt::Display,
{
self.details_updated_at = value.try_into().map_err(|e| {
format!("error converting supplied value for details_updated_at: {e}")
});
self
}
pub fn details_updated_by<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::std::option::Option<super::CommunityRoomV2DetailsUpdatedBy>,
>,
T::Error: ::std::fmt::Display,
{
self.details_updated_by = value.try_into().map_err(|e| {
format!("error converting supplied value for details_updated_by: {e}")
});
self
}
pub fn label<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::RoomLabel>,
T::Error: ::std::fmt::Display,
{
self.label = value
.try_into()
.map_err(|e| format!("error converting supplied value for label: {e}"));
self
}
pub fn offered<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.offered = value
.try_into()
.map_err(|e| format!("error converting supplied value for offered: {e}"));
self
}
pub fn owner_authority_valid_until<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
>,
T::Error: ::std::fmt::Display,
{
self.owner_authority_valid_until = value.try_into().map_err(|e| {
format!("error converting supplied value for owner_authority_valid_until: {e}")
});
self
}
pub fn room<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::HostedRoom>,
T::Error: ::std::fmt::Display,
{
self.room = value
.try_into()
.map_err(|e| format!("error converting supplied value for room: {e}"));
self
}
pub fn storage_config<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::StorageConfigId>>,
T::Error: ::std::fmt::Display,
{
self.storage_config = value
.try_into()
.map_err(|e| format!("error converting supplied value for storage_config: {e}"));
self
}
pub fn tags<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::RoomTags>>,
T::Error: ::std::fmt::Display,
{
self.tags = value
.try_into()
.map_err(|e| format!("error converting supplied value for tags: {e}"));
self
}
}
impl ::std::convert::TryFrom<CommunityRoomV2> for super::CommunityRoomV2 {
type Error = super::error::ConversionError;
fn try_from(
value: CommunityRoomV2,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
admitted: value.admitted?,
created_by: value.created_by?,
description: value.description?,
details_updated_at: value.details_updated_at?,
details_updated_by: value.details_updated_by?,
label: value.label?,
offered: value.offered?,
owner_authority_valid_until: value.owner_authority_valid_until?,
room: value.room?,
storage_config: value.storage_config?,
tags: value.tags?,
})
}
}
impl ::std::convert::From<super::CommunityRoomV2> for CommunityRoomV2 {
fn from(value: super::CommunityRoomV2) -> Self {
Self {
admitted: Ok(value.admitted),
created_by: Ok(value.created_by),
description: Ok(value.description),
details_updated_at: Ok(value.details_updated_at),
details_updated_by: Ok(value.details_updated_by),
label: Ok(value.label),
offered: Ok(value.offered),
owner_authority_valid_until: Ok(value.owner_authority_valid_until),
room: Ok(value.room),
storage_config: Ok(value.storage_config),
tags: Ok(value.tags),
}
}
}
#[derive(Clone, Debug)]
pub struct HostedRoom {
created_at: ::std::result::Result<u64, ::std::string::String>,
epoch: ::std::result::Result<u64, ::std::string::String>,
epoch_expires_at: ::std::result::Result<::std::option::Option<u64>, ::std::string::String>,
lifecycle: ::std::result::Result<super::HostedRoomLifecycle, ::std::string::String>,
mirror_of: ::std::result::Result<
::std::option::Option<super::HostedRoomMirrorOf>,
::std::string::String,
>,
owner_did: ::std::result::Result<super::HostedRoomOwnerDid, ::std::string::String>,
retention_days: ::std::result::Result<u64, ::std::string::String>,
retention_policy: ::std::result::Result<super::RetentionPolicy, ::std::string::String>,
room_id: ::std::result::Result<super::HostedRoomRoomId, ::std::string::String>,
updated_at: ::std::result::Result<u64, ::std::string::String>,
visibility: ::std::result::Result<super::Visibility, ::std::string::String>,
}
impl ::std::default::Default for HostedRoom {
fn default() -> Self {
Self {
created_at: Err("no value supplied for created_at".to_string()),
epoch: Err("no value supplied for epoch".to_string()),
epoch_expires_at: Ok(Default::default()),
lifecycle: Err("no value supplied for lifecycle".to_string()),
mirror_of: Ok(Default::default()),
owner_did: Err("no value supplied for owner_did".to_string()),
retention_days: Err("no value supplied for retention_days".to_string()),
retention_policy: Err("no value supplied for retention_policy".to_string()),
room_id: Err("no value supplied for room_id".to_string()),
updated_at: Err("no value supplied for updated_at".to_string()),
visibility: Err("no value supplied for visibility".to_string()),
}
}
}
impl HostedRoom {
pub fn created_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.created_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for created_at: {e}"));
self
}
pub fn epoch<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.epoch = value
.try_into()
.map_err(|e| format!("error converting supplied value for epoch: {e}"));
self
}
pub fn epoch_expires_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<u64>>,
T::Error: ::std::fmt::Display,
{
self.epoch_expires_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for epoch_expires_at: {e}"));
self
}
pub fn lifecycle<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::HostedRoomLifecycle>,
T::Error: ::std::fmt::Display,
{
self.lifecycle = value
.try_into()
.map_err(|e| format!("error converting supplied value for lifecycle: {e}"));
self
}
pub fn mirror_of<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::HostedRoomMirrorOf>>,
T::Error: ::std::fmt::Display,
{
self.mirror_of = value
.try_into()
.map_err(|e| format!("error converting supplied value for mirror_of: {e}"));
self
}
pub fn owner_did<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::HostedRoomOwnerDid>,
T::Error: ::std::fmt::Display,
{
self.owner_did = value
.try_into()
.map_err(|e| format!("error converting supplied value for owner_did: {e}"));
self
}
pub fn retention_days<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.retention_days = value
.try_into()
.map_err(|e| format!("error converting supplied value for retention_days: {e}"));
self
}
pub fn retention_policy<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::RetentionPolicy>,
T::Error: ::std::fmt::Display,
{
self.retention_policy = value
.try_into()
.map_err(|e| format!("error converting supplied value for retention_policy: {e}"));
self
}
pub fn room_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::HostedRoomRoomId>,
T::Error: ::std::fmt::Display,
{
self.room_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for room_id: {e}"));
self
}
pub fn updated_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.updated_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for updated_at: {e}"));
self
}
pub fn visibility<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::Visibility>,
T::Error: ::std::fmt::Display,
{
self.visibility = value
.try_into()
.map_err(|e| format!("error converting supplied value for visibility: {e}"));
self
}
}
impl ::std::convert::TryFrom<HostedRoom> for super::HostedRoom {
type Error = super::error::ConversionError;
fn try_from(
value: HostedRoom,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
created_at: value.created_at?,
epoch: value.epoch?,
epoch_expires_at: value.epoch_expires_at?,
lifecycle: value.lifecycle?,
mirror_of: value.mirror_of?,
owner_did: value.owner_did?,
retention_days: value.retention_days?,
retention_policy: value.retention_policy?,
room_id: value.room_id?,
updated_at: value.updated_at?,
visibility: value.visibility?,
})
}
}
impl ::std::convert::From<super::HostedRoom> for HostedRoom {
fn from(value: super::HostedRoom) -> Self {
Self {
created_at: Ok(value.created_at),
epoch: Ok(value.epoch),
epoch_expires_at: Ok(value.epoch_expires_at),
lifecycle: Ok(value.lifecycle),
mirror_of: Ok(value.mirror_of),
owner_did: Ok(value.owner_did),
retention_days: Ok(value.retention_days),
retention_policy: Ok(value.retention_policy),
room_id: Ok(value.room_id),
updated_at: Ok(value.updated_at),
visibility: Ok(value.visibility),
}
}
}
#[derive(Clone, Debug)]
pub struct Payload {
description: ::std::result::Result<
::std::option::Option<super::RoomDescription>,
::std::string::String,
>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
label: ::std::result::Result<super::RoomLabel, ::std::string::String>,
reason: ::std::result::Result<super::Reason, ::std::string::String>,
retention_days: ::std::result::Result<
::std::option::Option<::std::num::NonZeroU64>,
::std::string::String,
>,
retention_policy: ::std::result::Result<
::std::option::Option<super::RetentionPolicy>,
::std::string::String,
>,
storage_config: ::std::result::Result<
::std::option::Option<super::StorageConfigId>,
::std::string::String,
>,
tags: ::std::result::Result<::std::option::Option<super::RoomTags>, ::std::string::String>,
visibility: ::std::result::Result<super::Visibility, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
description: Ok(Default::default()),
ext: Ok(Default::default()),
label: Err("no value supplied for label".to_string()),
reason: Err("no value supplied for reason".to_string()),
retention_days: Ok(Default::default()),
retention_policy: Ok(Default::default()),
storage_config: Ok(Default::default()),
tags: Ok(Default::default()),
visibility: Err("no value supplied for visibility".to_string()),
}
}
}
impl Payload {
pub fn description<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::RoomDescription>>,
T::Error: ::std::fmt::Display,
{
self.description = value
.try_into()
.map_err(|e| format!("error converting supplied value for description: {e}"));
self
}
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn label<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::RoomLabel>,
T::Error: ::std::fmt::Display,
{
self.label = value
.try_into()
.map_err(|e| format!("error converting supplied value for label: {e}"));
self
}
pub fn reason<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::Reason>,
T::Error: ::std::fmt::Display,
{
self.reason = value
.try_into()
.map_err(|e| format!("error converting supplied value for reason: {e}"));
self
}
pub fn retention_days<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::num::NonZeroU64>>,
T::Error: ::std::fmt::Display,
{
self.retention_days = value
.try_into()
.map_err(|e| format!("error converting supplied value for retention_days: {e}"));
self
}
pub fn retention_policy<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::RetentionPolicy>>,
T::Error: ::std::fmt::Display,
{
self.retention_policy = value
.try_into()
.map_err(|e| format!("error converting supplied value for retention_policy: {e}"));
self
}
pub fn storage_config<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::StorageConfigId>>,
T::Error: ::std::fmt::Display,
{
self.storage_config = value
.try_into()
.map_err(|e| format!("error converting supplied value for storage_config: {e}"));
self
}
pub fn tags<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::RoomTags>>,
T::Error: ::std::fmt::Display,
{
self.tags = value
.try_into()
.map_err(|e| format!("error converting supplied value for tags: {e}"));
self
}
pub fn visibility<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::Visibility>,
T::Error: ::std::fmt::Display,
{
self.visibility = value
.try_into()
.map_err(|e| format!("error converting supplied value for visibility: {e}"));
self
}
}
impl ::std::convert::TryFrom<Payload> for super::Payload {
type Error = super::error::ConversionError;
fn try_from(value: Payload) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
description: value.description?,
ext: value.ext?,
label: value.label?,
reason: value.reason?,
retention_days: value.retention_days?,
retention_policy: value.retention_policy?,
storage_config: value.storage_config?,
tags: value.tags?,
visibility: value.visibility?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
description: Ok(value.description),
ext: Ok(value.ext),
label: Ok(value.label),
reason: Ok(value.reason),
retention_days: Ok(value.retention_days),
retention_policy: Ok(value.retention_policy),
storage_config: Ok(value.storage_config),
tags: Ok(value.tags),
visibility: Ok(value.visibility),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
room: ::std::result::Result<super::CommunityRoomV2, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
ext: Ok(Default::default()),
room: Err("no value supplied for room".to_string()),
}
}
}
impl Response {
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn room<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::CommunityRoomV2>,
T::Error: ::std::fmt::Display,
{
self.room = value
.try_into()
.map_err(|e| format!("error converting supplied value for room: {e}"));
self
}
}
impl ::std::convert::TryFrom<Response> for super::Response {
type Error = super::error::ConversionError;
fn try_from(value: Response) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
ext: value.ext?,
room: value.room?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
ext: Ok(value.ext),
room: Ok(value.room),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vtc/rooms/community/create/0.2";
const IS_PROOF_REQUIRED: bool = true;
const IS_ISSUED_AT_REQUIRED: bool = true;
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\n \"$defs\": {\n \"CommunityRoomV2\": {\n \"additionalProperties\": false,\n \"description\": \"What vtc/rooms/community/{create,get,list}/0.2 and vtc/rooms/community/update/0.1 return: `CommunityRoom` plus the details an administrator keeps track of a room by — `description`, `tags`, and who last changed them and when. A separate definition, not a change to `CommunityRoom`, so that the 0.1 versions of those tasks keep the exact shape they published. The room's creation is `room.createdAt` and `createdBy`.\",\n \"properties\": {\n \"admitted\": {\n \"description\": \"Members in state `admitted`.\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"createdBy\": {\n \"description\": \"The administrator who created it.\",\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"description\": {\n \"$ref\": \"#/$defs/RoomDescription\",\n \"description\": \"Absent when the room has none.\"\n },\n \"detailsUpdatedAt\": {\n \"description\": \"When `label`, `description` or `tags` last changed. Absent until the first change after creation. Distinct from `room.updatedAt`, which is the host record's and moves with the room's epoch and lifecycle.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"detailsUpdatedBy\": {\n \"description\": \"The administrator who made that change. Present exactly when `detailsUpdatedAt` is. The earlier values and who set them are in the community's audit trail, not here.\",\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"label\": {\n \"$ref\": \"#/$defs/RoomLabel\"\n },\n \"offered\": {\n \"description\": \"Offers not yet accepted or withdrawn.\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"ownerAuthorityValidUntil\": {\n \"description\": \"When the community's own `admin` authority over the room expires. A room whose owner's authority lapses can no longer advance its epoch, admit or remove; a community SHOULD renew it well before.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"room\": {\n \"$ref\": \"#/$defs/HostedRoom\"\n },\n \"storageConfig\": {\n \"$ref\": \"#/$defs/StorageConfigId\",\n \"description\": \"The storage config receiving the room's new uploads.\"\n },\n \"tags\": {\n \"$ref\": \"#/$defs/RoomTags\",\n \"description\": \"Absent or empty when the room has none.\"\n }\n },\n \"required\": [\n \"room\",\n \"label\",\n \"admitted\",\n \"offered\"\n ],\n \"title\": \"CommunityRoomV2\",\n \"type\": \"object\"\n },\n \"Ext\": {\n \"additionalProperties\": true,\n \"description\": \"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\n \"minProperties\": 1,\n \"propertyNames\": {\n \"pattern\": \"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"\n },\n \"title\": \"Ext\",\n \"type\": \"object\"\n },\n \"HostedRoom\": {\n \"additionalProperties\": false,\n \"description\": \"One room, as its host holds it — member for member the `HostedRoom` of vtc/rooms/list/0.1, which defines it inside its own payload schema. Nothing derived from the room's contents, and no member list: the host has none.\",\n \"properties\": {\n \"createdAt\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"epoch\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"epochExpiresAt\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"lifecycle\": {\n \"enum\": [\n \"live\",\n \"lapsed\",\n \"dormant\",\n \"reclaimable\"\n ],\n \"type\": \"string\"\n },\n \"mirrorOf\": {\n \"maxLength\": 2048,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"ownerDid\": {\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"retentionDays\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"retentionPolicy\": {\n \"$ref\": \"#/$defs/RetentionPolicy\"\n },\n \"roomId\": {\n \"maxLength\": 512,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"updatedAt\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"visibility\": {\n \"$ref\": \"#/$defs/Visibility\"\n }\n },\n \"required\": [\n \"roomId\",\n \"ownerDid\",\n \"visibility\",\n \"retentionPolicy\",\n \"epoch\",\n \"lifecycle\",\n \"retentionDays\",\n \"createdAt\",\n \"updatedAt\"\n ],\n \"title\": \"HostedRoom\",\n \"type\": \"object\"\n },\n \"Reason\": {\n \"description\": \"Why the administrator is making this change. Recorded with it in the audit trail. Attributed to its author on every surface and untrusted: it MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.\",\n \"maxLength\": 500,\n \"minLength\": 1,\n \"title\": \"Reason\",\n \"type\": \"string\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"Success response to vtc/rooms/community/create. Type https://trusttasks.org/spec/vtc/rooms/community/create/0.2#response. The room as created, owned by the community.\",\n \"properties\": {\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"room\": {\n \"$ref\": \"#/$defs/CommunityRoomV2\"\n }\n },\n \"required\": [\n \"room\"\n ],\n \"title\": \"VTC Rooms Community Create — response payload\",\n \"type\": \"object\"\n },\n \"RetentionPolicy\": {\n \"$comment\": \"Deliberately no JSON Schema `default`. A declared default is materialised by the generated bindings — the member becomes non-optional with a serde default — so an absent value would reappear as an explicit one on re-serialisation and break round-trip idempotence for every document written before this member existed. The meaning of absence is stated in prose, where a binding cannot act on it.\",\n \"description\": \"Whether a room keeps its history readable across a membership change, fixed at creation and immutable thereafter — like `Visibility`, and for the same reason: the rungs of an epoch key chain either exist for an epoch or they do not, and no later change of mind can seal key material that was never sealed or unseal what was already severed. `chained`: each advance produces an `EpochLink`, so every member reads the room's whole retained history however long they have been in it — what a **library** wants, at the cost of post-compromise security for record content, since a compromised current key then reaches every retained epoch. `fromJoin`: no rungs are produced, so a member reads only from the epoch their group state is at — what a **stream** wants, and what a room under a strict forward-secrecy obligation wants, at the cost that a joining member finds an empty-looking room and nobody can reread a record once their group state has moved past the epoch it was sealed under. Absent means `chained`; see the prose on why the absent case is the readable one.\",\n \"enum\": [\n \"chained\",\n \"fromJoin\"\n ],\n \"title\": \"RetentionPolicy\",\n \"type\": \"string\"\n },\n \"RoomDescription\": {\n \"description\": \"What the room is for, in a sentence or a short paragraph, written by an administrator: shown to administrators holding `vtc.rooms.manage` and to the members the room is offered to. Plain text — a consumer renders it as text, never as markup. Like `RoomLabel`, it is the community's own record as the room's owner: not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `description` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. It MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.\",\n \"maxLength\": 1000,\n \"minLength\": 1,\n \"title\": \"RoomDescription\",\n \"type\": \"string\"\n },\n \"RoomLabel\": {\n \"description\": \"A name for the room, chosen by an administrator: shown to administrators and to the members a room is offered to. Not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `name` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. MUST NOT carry personal data.\",\n \"maxLength\": 128,\n \"minLength\": 1,\n \"title\": \"RoomLabel\",\n \"type\": \"string\"\n },\n \"RoomTag\": {\n \"description\": \"A short identifier an administrator files a community-owned room under — `board`, `working-group`, `finance` — so the room list can be filtered. Lower-case letters, digits and hyphens, starting with a letter or digit. Owner-side tracking metadata for holders of `vtc.rooms.manage` only: never shown to members, never sent on the room's host path, and it confers nothing.\",\n \"maxLength\": 32,\n \"minLength\": 1,\n \"pattern\": \"^[a-z0-9][a-z0-9-]{0,31}$\",\n \"title\": \"RoomTag\",\n \"type\": \"string\"\n },\n \"RoomTags\": {\n \"description\": \"The room's tags, at most eight, as a set: order carries no meaning. An empty list means the room has none — a tag grants nothing, so empty has no more dangerous reading.\",\n \"items\": {\n \"$ref\": \"#/$defs/RoomTag\"\n },\n \"maxItems\": 8,\n \"title\": \"RoomTags\",\n \"type\": \"array\",\n \"uniqueItems\": true\n },\n \"StorageConfigId\": {\n \"description\": \"A storage config's identifier, chosen by the administrator who creates it and immutable thereafter: lowercase letters, digits and inner hyphens, at most 64 characters (`eu-s3-primary`, `walrus-main`). Unique within the community. Never reused after a config is retired, because blobs name their config by this value.\",\n \"maxLength\": 64,\n \"minLength\": 1,\n \"pattern\": \"^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$\",\n \"title\": \"StorageConfigId\",\n \"type\": \"string\"\n },\n \"Visibility\": {\n \"description\": \"How much of a room its host can see, fixed at creation and immutable thereafter. `open`: records are cleartext, searchable and fully audited. `attributed`: record content is sealed, and the host still learns which member acted. `private`: content is sealed and membership is presented in zero knowledge, so the host verifies that a member acted without learning which. Immutable because a downgrade cannot un-see cleartext and an upgrade would protect only what came after while presenting as though it protected everything.\",\n \"enum\": [\n \"open\",\n \"attributed\",\n \"private\"\n ],\n \"title\": \"Visibility\",\n \"type\": \"string\"\n }\n },\n \"$id\": \"https://trusttasks.org/spec/vtc/rooms/community/create/0.2\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"additionalProperties\": false,\n \"properties\": {\n \"description\": {\n \"$ref\": \"#/$defs/RoomDescription\",\n \"description\": \"What the room is for, shown beside its label. Absent: the room has none until an administrator gives it one with vtc/rooms/community/update.\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"label\": {\n \"$ref\": \"#/$defs/RoomLabel\"\n },\n \"reason\": {\n \"$ref\": \"#/$defs/Reason\"\n },\n \"retentionDays\": {\n \"description\": \"How long the room is kept after it lapses. Absent: the community's default.\",\n \"maximum\": 36500,\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"retentionPolicy\": {\n \"$ref\": \"#/$defs/RetentionPolicy\",\n \"description\": \"Whether the room keeps its history readable across a membership change. Immutable; absent means `chained`.\"\n },\n \"storageConfig\": {\n \"$ref\": \"#/$defs/StorageConfigId\",\n \"description\": \"The storage config to receive the room's uploads. Absent: what the community's rooms policy decides, else its default config.\"\n },\n \"tags\": {\n \"$ref\": \"#/$defs/RoomTags\",\n \"description\": \"Tags to file the room under, for administrators' filtering. Absent: none.\"\n },\n \"visibility\": {\n \"$ref\": \"#/$defs/Visibility\",\n \"description\": \"The tier, fixed for the life of the room. The community's rooms policy decides which it may create.\"\n }\n },\n \"required\": [\n \"label\",\n \"visibility\",\n \"reason\"\n ],\n \"title\": \"VTC Rooms Community Create — payload\",\n \"type\": \"object\"\n}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str =
"https://trusttasks.org/spec/vtc/rooms/community/create/0.2#response";
const IS_PROOF_REQUIRED: bool = true;
const IS_ISSUED_AT_REQUIRED: bool = true;
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\n \"$defs\": {\n \"CommunityRoomV2\": {\n \"additionalProperties\": false,\n \"description\": \"What vtc/rooms/community/{create,get,list}/0.2 and vtc/rooms/community/update/0.1 return: `CommunityRoom` plus the details an administrator keeps track of a room by — `description`, `tags`, and who last changed them and when. A separate definition, not a change to `CommunityRoom`, so that the 0.1 versions of those tasks keep the exact shape they published. The room's creation is `room.createdAt` and `createdBy`.\",\n \"properties\": {\n \"admitted\": {\n \"description\": \"Members in state `admitted`.\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"createdBy\": {\n \"description\": \"The administrator who created it.\",\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"description\": {\n \"$ref\": \"#/$defs/RoomDescription\",\n \"description\": \"Absent when the room has none.\"\n },\n \"detailsUpdatedAt\": {\n \"description\": \"When `label`, `description` or `tags` last changed. Absent until the first change after creation. Distinct from `room.updatedAt`, which is the host record's and moves with the room's epoch and lifecycle.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"detailsUpdatedBy\": {\n \"description\": \"The administrator who made that change. Present exactly when `detailsUpdatedAt` is. The earlier values and who set them are in the community's audit trail, not here.\",\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"label\": {\n \"$ref\": \"#/$defs/RoomLabel\"\n },\n \"offered\": {\n \"description\": \"Offers not yet accepted or withdrawn.\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"ownerAuthorityValidUntil\": {\n \"description\": \"When the community's own `admin` authority over the room expires. A room whose owner's authority lapses can no longer advance its epoch, admit or remove; a community SHOULD renew it well before.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"room\": {\n \"$ref\": \"#/$defs/HostedRoom\"\n },\n \"storageConfig\": {\n \"$ref\": \"#/$defs/StorageConfigId\",\n \"description\": \"The storage config receiving the room's new uploads.\"\n },\n \"tags\": {\n \"$ref\": \"#/$defs/RoomTags\",\n \"description\": \"Absent or empty when the room has none.\"\n }\n },\n \"required\": [\n \"room\",\n \"label\",\n \"admitted\",\n \"offered\"\n ],\n \"title\": \"CommunityRoomV2\",\n \"type\": \"object\"\n },\n \"Ext\": {\n \"additionalProperties\": true,\n \"description\": \"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\n \"minProperties\": 1,\n \"propertyNames\": {\n \"pattern\": \"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"\n },\n \"title\": \"Ext\",\n \"type\": \"object\"\n },\n \"HostedRoom\": {\n \"additionalProperties\": false,\n \"description\": \"One room, as its host holds it — member for member the `HostedRoom` of vtc/rooms/list/0.1, which defines it inside its own payload schema. Nothing derived from the room's contents, and no member list: the host has none.\",\n \"properties\": {\n \"createdAt\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"epoch\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"epochExpiresAt\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"lifecycle\": {\n \"enum\": [\n \"live\",\n \"lapsed\",\n \"dormant\",\n \"reclaimable\"\n ],\n \"type\": \"string\"\n },\n \"mirrorOf\": {\n \"maxLength\": 2048,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"ownerDid\": {\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"retentionDays\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"retentionPolicy\": {\n \"$ref\": \"#/$defs/RetentionPolicy\"\n },\n \"roomId\": {\n \"maxLength\": 512,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"updatedAt\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"visibility\": {\n \"$ref\": \"#/$defs/Visibility\"\n }\n },\n \"required\": [\n \"roomId\",\n \"ownerDid\",\n \"visibility\",\n \"retentionPolicy\",\n \"epoch\",\n \"lifecycle\",\n \"retentionDays\",\n \"createdAt\",\n \"updatedAt\"\n ],\n \"title\": \"HostedRoom\",\n \"type\": \"object\"\n },\n \"Reason\": {\n \"description\": \"Why the administrator is making this change. Recorded with it in the audit trail. Attributed to its author on every surface and untrusted: it MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.\",\n \"maxLength\": 500,\n \"minLength\": 1,\n \"title\": \"Reason\",\n \"type\": \"string\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"Success response to vtc/rooms/community/create. Type https://trusttasks.org/spec/vtc/rooms/community/create/0.2#response. The room as created, owned by the community.\",\n \"properties\": {\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"room\": {\n \"$ref\": \"#/$defs/CommunityRoomV2\"\n }\n },\n \"required\": [\n \"room\"\n ],\n \"title\": \"VTC Rooms Community Create — response payload\",\n \"type\": \"object\"\n },\n \"RetentionPolicy\": {\n \"$comment\": \"Deliberately no JSON Schema `default`. A declared default is materialised by the generated bindings — the member becomes non-optional with a serde default — so an absent value would reappear as an explicit one on re-serialisation and break round-trip idempotence for every document written before this member existed. The meaning of absence is stated in prose, where a binding cannot act on it.\",\n \"description\": \"Whether a room keeps its history readable across a membership change, fixed at creation and immutable thereafter — like `Visibility`, and for the same reason: the rungs of an epoch key chain either exist for an epoch or they do not, and no later change of mind can seal key material that was never sealed or unseal what was already severed. `chained`: each advance produces an `EpochLink`, so every member reads the room's whole retained history however long they have been in it — what a **library** wants, at the cost of post-compromise security for record content, since a compromised current key then reaches every retained epoch. `fromJoin`: no rungs are produced, so a member reads only from the epoch their group state is at — what a **stream** wants, and what a room under a strict forward-secrecy obligation wants, at the cost that a joining member finds an empty-looking room and nobody can reread a record once their group state has moved past the epoch it was sealed under. Absent means `chained`; see the prose on why the absent case is the readable one.\",\n \"enum\": [\n \"chained\",\n \"fromJoin\"\n ],\n \"title\": \"RetentionPolicy\",\n \"type\": \"string\"\n },\n \"RoomDescription\": {\n \"description\": \"What the room is for, in a sentence or a short paragraph, written by an administrator: shown to administrators holding `vtc.rooms.manage` and to the members the room is offered to. Plain text — a consumer renders it as text, never as markup. Like `RoomLabel`, it is the community's own record as the room's owner: not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `description` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. It MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.\",\n \"maxLength\": 1000,\n \"minLength\": 1,\n \"title\": \"RoomDescription\",\n \"type\": \"string\"\n },\n \"RoomLabel\": {\n \"description\": \"A name for the room, chosen by an administrator: shown to administrators and to the members a room is offered to. Not part of the room's identity and never in anything a room's host can read. From `vtc/rooms/community/create` 0.3 and `vtc/rooms/community/update` 0.2 the community also writes it, through its own VTA, as the `name` of the room's own profile (`RoomProfile` in rooms/_shared), sealed inside the room for its members; earlier versions keep it out of the room altogether. MUST NOT carry personal data.\",\n \"maxLength\": 128,\n \"minLength\": 1,\n \"title\": \"RoomLabel\",\n \"type\": \"string\"\n },\n \"RoomTag\": {\n \"description\": \"A short identifier an administrator files a community-owned room under — `board`, `working-group`, `finance` — so the room list can be filtered. Lower-case letters, digits and hyphens, starting with a letter or digit. Owner-side tracking metadata for holders of `vtc.rooms.manage` only: never shown to members, never sent on the room's host path, and it confers nothing.\",\n \"maxLength\": 32,\n \"minLength\": 1,\n \"pattern\": \"^[a-z0-9][a-z0-9-]{0,31}$\",\n \"title\": \"RoomTag\",\n \"type\": \"string\"\n },\n \"RoomTags\": {\n \"description\": \"The room's tags, at most eight, as a set: order carries no meaning. An empty list means the room has none — a tag grants nothing, so empty has no more dangerous reading.\",\n \"items\": {\n \"$ref\": \"#/$defs/RoomTag\"\n },\n \"maxItems\": 8,\n \"title\": \"RoomTags\",\n \"type\": \"array\",\n \"uniqueItems\": true\n },\n \"StorageConfigId\": {\n \"description\": \"A storage config's identifier, chosen by the administrator who creates it and immutable thereafter: lowercase letters, digits and inner hyphens, at most 64 characters (`eu-s3-primary`, `walrus-main`). Unique within the community. Never reused after a config is retired, because blobs name their config by this value.\",\n \"maxLength\": 64,\n \"minLength\": 1,\n \"pattern\": \"^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$\",\n \"title\": \"StorageConfigId\",\n \"type\": \"string\"\n },\n \"Visibility\": {\n \"description\": \"How much of a room its host can see, fixed at creation and immutable thereafter. `open`: records are cleartext, searchable and fully audited. `attributed`: record content is sealed, and the host still learns which member acted. `private`: content is sealed and membership is presented in zero knowledge, so the host verifies that a member acted without learning which. Immutable because a downgrade cannot un-see cleartext and an upgrade would protect only what came after while presenting as though it protected everything.\",\n \"enum\": [\n \"open\",\n \"attributed\",\n \"private\"\n ],\n \"title\": \"Visibility\",\n \"type\": \"string\"\n }\n },\n \"$ref\": \"#/$defs/Response\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\"\n}\n",
);
}
impl crate::RequestPayload for Payload {
type Response = Response;
}
/// The extended error codes this specification declares (SPEC §7.3 item 9,
/// §8.5), in declaration order. Empty when it declares none.
pub const ERROR_CODES: &[crate::DeclaredErrorCode] = &[
error_codes::VISIBILITY_NOT_PERMITTED,
error_codes::UNKNOWN_STORAGE_CONFIG,
error_codes::NO_KEY_HOLDER,
error_codes::KEY_HOLDER_UNAVAILABLE,
error_codes::KEY_HOLDER_REFUSED,
];
/// One constant per extended error code this specification declares
/// (SPEC §7.3 item 9), named for its local part.
///
/// Emit these rather than a string literal: the code is read from the
/// specification, so it cannot name a code the specification never
/// declared.
pub mod error_codes {
/// `vtc/rooms/community/create:visibilityNotPermitted`
///
/// The community's rooms policy does not let it own a room at this tier.
///
/// Declared `retryable: false`.
pub const VISIBILITY_NOT_PERMITTED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/rooms/community/create:visibilityNotPermitted",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `vtc/rooms/community/create:unknownStorageConfig`
///
/// `storageConfig` names no config, or one that is not `active`.
///
/// Declared `retryable: false`.
pub const UNKNOWN_STORAGE_CONFIG: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/rooms/community/create:unknownStorageConfig",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `vtc/rooms/community/create:noKeyHolder`
///
/// The community has no link to a VTA that can hold the room's keys. Its host's operator configures one.
///
/// Declared `retryable: false`.
pub const NO_KEY_HOLDER: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/rooms/community/create:noKeyHolder",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `vtc/rooms/community/create:keyHolderUnavailable`
///
/// The community's VTA did not answer. Nothing was stored; a DID it may have minted is named in `details.roomId` so an operator can retire it.
///
/// Declared `retryable: true`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const KEY_HOLDER_UNAVAILABLE: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/rooms/community/create:keyHolderUnavailable",
retryable: true,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"roomId\":{\"maxLength\":512,\"type\":\"string\"}},\"type\":\"object\"}",
),
};
/// `vtc/rooms/community/create:keyHolderRefused`
///
/// The community's VTA refused a step. Its own code and message are carried in `details`. Nothing was stored.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const KEY_HOLDER_REFUSED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/rooms/community/create:keyHolderRefused",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"code\":{\"maxLength\":128,\"type\":\"string\"},\"message\":{\"maxLength\":500,\"type\":\"string\"}},\"type\":\"object\"}",
),
};
}