//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `vtc/members/list`. Version: `0.2`.
/// Why this specification version is deprecated (SPEC "Superseded and
/// Withdrawn Versions"), or `None` while it is current.
pub const DEPRECATION: Option<&str> = None;
#[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())
}
}
}
///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.
///
#[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`
///
#[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 community member as the maintainer sees it: the membership record joined with its ACL role.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct MemberResponse {
///Id of the member's current role credential — a community-issued Verifiable Authority Credential conferring `role:<name>` — if issued. Formerly `currentRoleVecId`.
#[serde(
rename = "currentRoleVacId",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub current_role_vac_id: ::std::option::Option<::std::string::String>,
///Id of the member's current Verifiable Membership Credential, if issued.
#[serde(
rename = "currentVmcId",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub current_vmc_id: ::std::option::Option<::std::string::String>,
///How the member's record is handled on departure.
#[serde(rename = "departurePreference")]
pub departure_preference: MemberResponseDeparturePreference,
///The member's DID.
pub did: MemberResponseDid,
///Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation).
pub extensions: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
#[serde(rename = "joinedAt")]
pub joined_at: ::chrono::DateTime<::chrono::offset::Utc>,
///Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart.
#[serde(
rename = "joinedViaInvitation",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub joined_via_invitation: ::std::option::Option<bool>,
///Optional human-readable label.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub label: ::std::option::Option<MemberResponseLabel>,
///`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here.
#[serde(
rename = "memberVmcId",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub member_vmc_id: ::std::option::Option<::std::string::String>,
///When that reciprocal credential was received. Paired with `memberVmcId`.
#[serde(
rename = "memberVmcReceivedAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub member_vmc_received_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
///Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub personhood: ::std::option::Option<bool>,
///When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag.
#[serde(
rename = "personhoodAssertedAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub personhood_asserted_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
///Whether the member consented to being published in the community directory.
#[serde(rename = "publishConsent")]
pub publish_consent: bool,
///The member's role in wire form (e.g. `admin`, `moderator`, `custom:editor`).
pub role: MemberResponseRole,
///The member's slot on the community's membership status list, when allocated.
#[serde(
rename = "statusListIndex",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub status_list_index: ::std::option::Option<i64>,
}
impl MemberResponse {
pub fn builder() -> builder::MemberResponse {
Default::default()
}
}
///How the member's record is handled on departure.
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum MemberResponseDeparturePreference {
#[serde(rename = "purge")]
Purge,
#[serde(rename = "tombstone")]
Tombstone,
#[serde(rename = "historical")]
Historical,
#[serde(rename = "policydefault")]
Policydefault,
}
impl ::std::fmt::Display for MemberResponseDeparturePreference {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Purge => f.write_str("purge"),
Self::Tombstone => f.write_str("tombstone"),
Self::Historical => f.write_str("historical"),
Self::Policydefault => f.write_str("policydefault"),
}
}
}
impl ::std::str::FromStr for MemberResponseDeparturePreference {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"purge" => Ok(Self::Purge),
"tombstone" => Ok(Self::Tombstone),
"historical" => Ok(Self::Historical),
"policydefault" => Ok(Self::Policydefault),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for MemberResponseDeparturePreference {
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 MemberResponseDeparturePreference {
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 MemberResponseDeparturePreference {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///The member's DID.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct MemberResponseDid(::std::string::String);
impl ::std::ops::Deref for MemberResponseDid {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<MemberResponseDid> for ::std::string::String {
fn from(value: MemberResponseDid) -> Self {
value.0
}
}
impl ::std::str::FromStr for MemberResponseDid {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for MemberResponseDid {
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 MemberResponseDid {
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 MemberResponseDid {
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 MemberResponseDid {
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())
})
}
}
///Optional human-readable label.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct MemberResponseLabel(::std::string::String);
impl ::std::ops::Deref for MemberResponseLabel {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<MemberResponseLabel> for ::std::string::String {
fn from(value: MemberResponseLabel) -> Self {
value.0
}
}
impl ::std::str::FromStr for MemberResponseLabel {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 256usize {
return Err("longer than 256 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for MemberResponseLabel {
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 MemberResponseLabel {
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 MemberResponseLabel {
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 MemberResponseLabel {
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 member's role in wire form (e.g. `admin`, `moderator`, `custom:editor`).
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct MemberResponseRole(::std::string::String);
impl ::std::ops::Deref for MemberResponseRole {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<MemberResponseRole> for ::std::string::String {
fn from(value: MemberResponseRole) -> Self {
value.0
}
}
impl ::std::str::FromStr for MemberResponseRole {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for MemberResponseRole {
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 MemberResponseRole {
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 MemberResponseRole {
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 MemberResponseRole {
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`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
///An opaque continuation token from a previous response's `nextCursor`; a responder MUST NOT accept a cursor it did not issue.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub cursor: ::std::option::Option<::std::string::String>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///The most items to return, at most 200; the responder chooses a default (50) and MAY return fewer.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub limit: ::std::option::Option<::std::num::NonZeroU64>,
///Filter to members with this role (wire form, e.g. `admin`, `custom:editor`).
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub role: ::std::option::Option<PayloadRole>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
cursor: Default::default(),
ext: Default::default(),
limit: Default::default(),
role: Default::default(),
}
}
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///Filter to members with this role (wire form, e.g. `admin`, `custom:editor`).
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PayloadRole(::std::string::String);
impl ::std::ops::Deref for PayloadRole {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PayloadRole> for ::std::string::String {
fn from(value: PayloadRole) -> Self {
value.0
}
}
impl ::std::str::FromStr for PayloadRole {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for PayloadRole {
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 PayloadRole {
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 PayloadRole {
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 PayloadRole {
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())
})
}
}
///`Response`
///
#[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 items: ::std::vec::Vec<MemberResponse>,
///Continuation token for the next page; pass it back as `cursor`. Absent on the last page — never `null`.
#[serde(
rename = "nextCursor",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub next_cursor: ::std::option::Option<::std::string::String>,
///Approximate total matching members, when the maintainer can cheaply estimate it.
#[serde(
rename = "totalEstimate",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub total_estimate: ::std::option::Option<i64>,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
/// Types for composing complex structures.
pub mod builder {
#[derive(Clone, Debug)]
pub struct MemberResponse {
current_role_vac_id: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
current_vmc_id: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
departure_preference:
::std::result::Result<super::MemberResponseDeparturePreference, ::std::string::String>,
did: ::std::result::Result<super::MemberResponseDid, ::std::string::String>,
extensions: ::std::result::Result<
::serde_json::Map<::std::string::String, ::serde_json::Value>,
::std::string::String,
>,
joined_at:
::std::result::Result<::chrono::DateTime<::chrono::offset::Utc>, ::std::string::String>,
joined_via_invitation:
::std::result::Result<::std::option::Option<bool>, ::std::string::String>,
label: ::std::result::Result<
::std::option::Option<super::MemberResponseLabel>,
::std::string::String,
>,
member_vmc_id: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
member_vmc_received_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
personhood: ::std::result::Result<::std::option::Option<bool>, ::std::string::String>,
personhood_asserted_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
publish_consent: ::std::result::Result<bool, ::std::string::String>,
role: ::std::result::Result<super::MemberResponseRole, ::std::string::String>,
status_list_index: ::std::result::Result<::std::option::Option<i64>, ::std::string::String>,
}
impl ::std::default::Default for MemberResponse {
fn default() -> Self {
Self {
current_role_vac_id: Ok(Default::default()),
current_vmc_id: Ok(Default::default()),
departure_preference: Err("no value supplied for departure_preference".to_string()),
did: Err("no value supplied for did".to_string()),
extensions: Err("no value supplied for extensions".to_string()),
joined_at: Err("no value supplied for joined_at".to_string()),
joined_via_invitation: Ok(Default::default()),
label: Ok(Default::default()),
member_vmc_id: Ok(Default::default()),
member_vmc_received_at: Ok(Default::default()),
personhood: Ok(Default::default()),
personhood_asserted_at: Ok(Default::default()),
publish_consent: Err("no value supplied for publish_consent".to_string()),
role: Err("no value supplied for role".to_string()),
status_list_index: Ok(Default::default()),
}
}
}
impl MemberResponse {
pub fn current_role_vac_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.current_role_vac_id = value.try_into().map_err(|e| {
format!("error converting supplied value for current_role_vac_id: {e}")
});
self
}
pub fn current_vmc_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.current_vmc_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for current_vmc_id: {e}"));
self
}
pub fn departure_preference<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::MemberResponseDeparturePreference>,
T::Error: ::std::fmt::Display,
{
self.departure_preference = value.try_into().map_err(|e| {
format!("error converting supplied value for departure_preference: {e}")
});
self
}
pub fn did<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::MemberResponseDid>,
T::Error: ::std::fmt::Display,
{
self.did = value
.try_into()
.map_err(|e| format!("error converting supplied value for did: {e}"));
self
}
pub fn extensions<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::serde_json::Map<::std::string::String, ::serde_json::Value>,
>,
T::Error: ::std::fmt::Display,
{
self.extensions = value
.try_into()
.map_err(|e| format!("error converting supplied value for extensions: {e}"));
self
}
pub fn joined_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::chrono::DateTime<::chrono::offset::Utc>>,
T::Error: ::std::fmt::Display,
{
self.joined_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for joined_at: {e}"));
self
}
pub fn joined_via_invitation<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<bool>>,
T::Error: ::std::fmt::Display,
{
self.joined_via_invitation = value.try_into().map_err(|e| {
format!("error converting supplied value for joined_via_invitation: {e}")
});
self
}
pub fn label<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::MemberResponseLabel>>,
T::Error: ::std::fmt::Display,
{
self.label = value
.try_into()
.map_err(|e| format!("error converting supplied value for label: {e}"));
self
}
pub fn member_vmc_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.member_vmc_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for member_vmc_id: {e}"));
self
}
pub fn member_vmc_received_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.member_vmc_received_at = value.try_into().map_err(|e| {
format!("error converting supplied value for member_vmc_received_at: {e}")
});
self
}
pub fn personhood<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<bool>>,
T::Error: ::std::fmt::Display,
{
self.personhood = value
.try_into()
.map_err(|e| format!("error converting supplied value for personhood: {e}"));
self
}
pub fn personhood_asserted_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.personhood_asserted_at = value.try_into().map_err(|e| {
format!("error converting supplied value for personhood_asserted_at: {e}")
});
self
}
pub fn publish_consent<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<bool>,
T::Error: ::std::fmt::Display,
{
self.publish_consent = value
.try_into()
.map_err(|e| format!("error converting supplied value for publish_consent: {e}"));
self
}
pub fn role<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::MemberResponseRole>,
T::Error: ::std::fmt::Display,
{
self.role = value
.try_into()
.map_err(|e| format!("error converting supplied value for role: {e}"));
self
}
pub fn status_list_index<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<i64>>,
T::Error: ::std::fmt::Display,
{
self.status_list_index = value
.try_into()
.map_err(|e| format!("error converting supplied value for status_list_index: {e}"));
self
}
}
impl ::std::convert::TryFrom<MemberResponse> for super::MemberResponse {
type Error = super::error::ConversionError;
fn try_from(
value: MemberResponse,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
current_role_vac_id: value.current_role_vac_id?,
current_vmc_id: value.current_vmc_id?,
departure_preference: value.departure_preference?,
did: value.did?,
extensions: value.extensions?,
joined_at: value.joined_at?,
joined_via_invitation: value.joined_via_invitation?,
label: value.label?,
member_vmc_id: value.member_vmc_id?,
member_vmc_received_at: value.member_vmc_received_at?,
personhood: value.personhood?,
personhood_asserted_at: value.personhood_asserted_at?,
publish_consent: value.publish_consent?,
role: value.role?,
status_list_index: value.status_list_index?,
})
}
}
impl ::std::convert::From<super::MemberResponse> for MemberResponse {
fn from(value: super::MemberResponse) -> Self {
Self {
current_role_vac_id: Ok(value.current_role_vac_id),
current_vmc_id: Ok(value.current_vmc_id),
departure_preference: Ok(value.departure_preference),
did: Ok(value.did),
extensions: Ok(value.extensions),
joined_at: Ok(value.joined_at),
joined_via_invitation: Ok(value.joined_via_invitation),
label: Ok(value.label),
member_vmc_id: Ok(value.member_vmc_id),
member_vmc_received_at: Ok(value.member_vmc_received_at),
personhood: Ok(value.personhood),
personhood_asserted_at: Ok(value.personhood_asserted_at),
publish_consent: Ok(value.publish_consent),
role: Ok(value.role),
status_list_index: Ok(value.status_list_index),
}
}
}
#[derive(Clone, Debug)]
pub struct Payload {
cursor: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
limit: ::std::result::Result<
::std::option::Option<::std::num::NonZeroU64>,
::std::string::String,
>,
role:
::std::result::Result<::std::option::Option<super::PayloadRole>, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
cursor: Ok(Default::default()),
ext: Ok(Default::default()),
limit: Ok(Default::default()),
role: Ok(Default::default()),
}
}
}
impl Payload {
pub fn cursor<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.cursor = value
.try_into()
.map_err(|e| format!("error converting supplied value for cursor: {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 limit<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::num::NonZeroU64>>,
T::Error: ::std::fmt::Display,
{
self.limit = value
.try_into()
.map_err(|e| format!("error converting supplied value for limit: {e}"));
self
}
pub fn role<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::PayloadRole>>,
T::Error: ::std::fmt::Display,
{
self.role = value
.try_into()
.map_err(|e| format!("error converting supplied value for role: {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 {
cursor: value.cursor?,
ext: value.ext?,
limit: value.limit?,
role: value.role?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
cursor: Ok(value.cursor),
ext: Ok(value.ext),
limit: Ok(value.limit),
role: Ok(value.role),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
items: ::std::result::Result<::std::vec::Vec<super::MemberResponse>, ::std::string::String>,
next_cursor: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
total_estimate: ::std::result::Result<::std::option::Option<i64>, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
ext: Ok(Default::default()),
items: Err("no value supplied for items".to_string()),
next_cursor: Ok(Default::default()),
total_estimate: Ok(Default::default()),
}
}
}
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 items<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::vec::Vec<super::MemberResponse>>,
T::Error: ::std::fmt::Display,
{
self.items = value
.try_into()
.map_err(|e| format!("error converting supplied value for items: {e}"));
self
}
pub fn next_cursor<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.next_cursor = value
.try_into()
.map_err(|e| format!("error converting supplied value for next_cursor: {e}"));
self
}
pub fn total_estimate<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<i64>>,
T::Error: ::std::fmt::Display,
{
self.total_estimate = value
.try_into()
.map_err(|e| format!("error converting supplied value for total_estimate: {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?,
items: value.items?,
next_cursor: value.next_cursor?,
total_estimate: value.total_estimate?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
ext: Ok(value.ext),
items: Ok(value.items),
next_cursor: Ok(value.next_cursor),
total_estimate: Ok(value.total_estimate),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vtc/members/list/0.2";
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\"$defs\":{\"Ext\":{\"additionalProperties\":true,\"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.\",\"minProperties\":1,\"propertyNames\":{\"pattern\":\"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"},\"title\":\"Ext\",\"type\":\"object\"},\"MemberResponse\":{\"$anchor\":\"memberResponse\",\"additionalProperties\":false,\"description\":\"One community member as the maintainer sees it: the membership record joined with its ACL role.\",\"properties\":{\"currentRoleVacId\":{\"description\":\"Id of the member's current role credential — a community-issued Verifiable Authority Credential conferring `role:<name>` — if issued. Formerly `currentRoleVecId`.\",\"type\":[\"string\",\"null\"]},\"currentVmcId\":{\"description\":\"Id of the member's current Verifiable Membership Credential, if issued.\",\"type\":[\"string\",\"null\"]},\"departurePreference\":{\"description\":\"How the member's record is handled on departure.\",\"enum\":[\"purge\",\"tombstone\",\"historical\",\"policydefault\"],\"type\":\"string\"},\"did\":{\"description\":\"The member's DID.\",\"minLength\":1,\"type\":\"string\"},\"extensions\":{\"description\":\"Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation).\",\"type\":\"object\"},\"joinedAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"joinedViaInvitation\":{\"description\":\"Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart.\",\"type\":\"boolean\"},\"label\":{\"description\":\"Optional human-readable label.\",\"maxLength\":256,\"type\":[\"string\",\"null\"]},\"memberVmcId\":{\"description\":\"`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here.\",\"type\":[\"string\",\"null\"]},\"memberVmcReceivedAt\":{\"description\":\"When that reciprocal credential was received. Paired with `memberVmcId`.\",\"format\":\"date-time\",\"type\":[\"string\",\"null\"]},\"personhood\":{\"description\":\"Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision.\",\"type\":\"boolean\"},\"personhoodAssertedAt\":{\"description\":\"When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag.\",\"format\":\"date-time\",\"type\":[\"string\",\"null\"]},\"publishConsent\":{\"description\":\"Whether the member consented to being published in the community directory.\",\"type\":\"boolean\"},\"role\":{\"description\":\"The member's role in wire form (e.g. `admin`, `moderator`, `custom:editor`).\",\"minLength\":1,\"type\":\"string\"},\"statusListIndex\":{\"description\":\"The member's slot on the community's membership status list, when allocated.\",\"type\":[\"integer\",\"null\"]}},\"required\":[\"did\",\"role\",\"joinedAt\",\"publishConsent\",\"departurePreference\",\"extensions\"],\"title\":\"MemberResponse\",\"type\":\"object\"},\"Response\":{\"$anchor\":\"response\",\"additionalProperties\":false,\"properties\":{\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"items\":{\"items\":{\"$ref\":\"#/$defs/MemberResponse\"},\"type\":\"array\"},\"nextCursor\":{\"description\":\"Continuation token for the next page; pass it back as `cursor`. Absent on the last page — never `null`.\",\"type\":\"string\"},\"totalEstimate\":{\"description\":\"Approximate total matching members, when the maintainer can cheaply estimate it.\",\"type\":[\"integer\",\"null\"]}},\"required\":[\"items\"],\"title\":\"VTC Members List — response payload\",\"type\":\"object\"}},\"$id\":\"https://trusttasks.org/spec/vtc/members/list/0.2\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"additionalProperties\":false,\"properties\":{\"cursor\":{\"description\":\"An opaque continuation token from a previous response's `nextCursor`; a responder MUST NOT accept a cursor it did not issue.\",\"type\":\"string\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"limit\":{\"description\":\"The most items to return, at most 200; the responder chooses a default (50) and MAY return fewer.\",\"maximum\":200,\"minimum\":1,\"type\":\"integer\"},\"role\":{\"description\":\"Filter to members with this role (wire form, e.g. `admin`, `custom:editor`).\",\"minLength\":1,\"type\":\"string\"}},\"title\":\"VTC Members List — payload\",\"type\":\"object\"}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vtc/members/list/0.2#response";
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\"$defs\":{\"Ext\":{\"additionalProperties\":true,\"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.\",\"minProperties\":1,\"propertyNames\":{\"pattern\":\"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"},\"title\":\"Ext\",\"type\":\"object\"},\"MemberResponse\":{\"$anchor\":\"memberResponse\",\"additionalProperties\":false,\"description\":\"One community member as the maintainer sees it: the membership record joined with its ACL role.\",\"properties\":{\"currentRoleVacId\":{\"description\":\"Id of the member's current role credential — a community-issued Verifiable Authority Credential conferring `role:<name>` — if issued. Formerly `currentRoleVecId`.\",\"type\":[\"string\",\"null\"]},\"currentVmcId\":{\"description\":\"Id of the member's current Verifiable Membership Credential, if issued.\",\"type\":[\"string\",\"null\"]},\"departurePreference\":{\"description\":\"How the member's record is handled on departure.\",\"enum\":[\"purge\",\"tombstone\",\"historical\",\"policydefault\"],\"type\":\"string\"},\"did\":{\"description\":\"The member's DID.\",\"minLength\":1,\"type\":\"string\"},\"extensions\":{\"description\":\"Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation).\",\"type\":\"object\"},\"joinedAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"joinedViaInvitation\":{\"description\":\"Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart.\",\"type\":\"boolean\"},\"label\":{\"description\":\"Optional human-readable label.\",\"maxLength\":256,\"type\":[\"string\",\"null\"]},\"memberVmcId\":{\"description\":\"`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here.\",\"type\":[\"string\",\"null\"]},\"memberVmcReceivedAt\":{\"description\":\"When that reciprocal credential was received. Paired with `memberVmcId`.\",\"format\":\"date-time\",\"type\":[\"string\",\"null\"]},\"personhood\":{\"description\":\"Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision.\",\"type\":\"boolean\"},\"personhoodAssertedAt\":{\"description\":\"When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag.\",\"format\":\"date-time\",\"type\":[\"string\",\"null\"]},\"publishConsent\":{\"description\":\"Whether the member consented to being published in the community directory.\",\"type\":\"boolean\"},\"role\":{\"description\":\"The member's role in wire form (e.g. `admin`, `moderator`, `custom:editor`).\",\"minLength\":1,\"type\":\"string\"},\"statusListIndex\":{\"description\":\"The member's slot on the community's membership status list, when allocated.\",\"type\":[\"integer\",\"null\"]}},\"required\":[\"did\",\"role\",\"joinedAt\",\"publishConsent\",\"departurePreference\",\"extensions\"],\"title\":\"MemberResponse\",\"type\":\"object\"},\"Response\":{\"$anchor\":\"response\",\"additionalProperties\":false,\"properties\":{\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"items\":{\"items\":{\"$ref\":\"#/$defs/MemberResponse\"},\"type\":\"array\"},\"nextCursor\":{\"description\":\"Continuation token for the next page; pass it back as `cursor`. Absent on the last page — never `null`.\",\"type\":\"string\"},\"totalEstimate\":{\"description\":\"Approximate total matching members, when the maintainer can cheaply estimate it.\",\"type\":[\"integer\",\"null\"]}},\"required\":[\"items\"],\"title\":\"VTC Members List — response payload\",\"type\":\"object\"}},\"$ref\":\"#/$defs/Response\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\"}\n",
);
}
impl crate::RequestPayload for Payload {
type Response = Response;
}
/// The earlier `MAJOR.MINOR` of this slug that this version declares it
/// extends (front matter `extends`, SPEC §5.2 "Declared extension"), or
/// `None`. Only the direct declaration; walk a chain with
/// [`crate::extension::extends_for`].
pub const EXTENDS: Option<&str> = None;
/// 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] = &[];