//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `vtc/directory/card/assert`. Version: `0.1`.
#[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())
}
}
}
///A content-addressed image held in the community's blob store — an avatar or an `image` field. At most 256 KiB, images only, re-encoded by the community on upload (vtc/directory/images/upload: metadata stripped, dimensions capped) so its digest does not link the member across communities. A viewer reads the bytes with vtc/directory/images/get, which answers only where the same projection shows the value. `url` and `urlExpiresAt` MAY appear in a projection: a short-lived URL the community checks against the same projection, so a member-only image is never a public URL. A community that does not offer one leaves both out.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "CardBlobRef",
/// "description": "A content-addressed image held in the community's blob store — an avatar or an `image` field. At most 256 KiB, images only, re-encoded by the community on upload (vtc/directory/images/upload: metadata stripped, dimensions capped) so its digest does not link the member across communities. A viewer reads the bytes with vtc/directory/images/get, which answers only where the same projection shows the value. `url` and `urlExpiresAt` MAY appear in a projection: a short-lived URL the community checks against the same projection, so a member-only image is never a public URL. A community that does not offer one leaves both out.",
/// "type": "object",
/// "required": [
/// "mediaType",
/// "sha256"
/// ],
/// "properties": {
/// "mediaType": {
/// "description": "Media type of the stored bytes.",
/// "type": "string",
/// "enum": [
/// "image/png",
/// "image/jpeg",
/// "image/webp",
/// "image/avif"
/// ]
/// },
/// "sha256": {
/// "description": "Lowercase hex SHA-256 of the stored, re-encoded bytes.",
/// "type": "string",
/// "pattern": "^[0-9a-f]{64}$"
/// },
/// "size": {
/// "description": "Size in bytes of the stored bytes.",
/// "type": "integer",
/// "maximum": 262144.0,
/// "minimum": 1.0
/// },
/// "url": {
/// "description": "Projection only: a URL the viewer can fetch the image from until `urlExpiresAt`.",
/// "type": "string",
/// "format": "uri",
/// "maxLength": 2048
/// },
/// "urlExpiresAt": {
/// "description": "Projection only: when `url` stops working.",
/// "type": "string",
/// "format": "date-time"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct CardBlobRef {
///Media type of the stored bytes.
#[serde(rename = "mediaType")]
pub media_type: CardBlobRefMediaType,
///Lowercase hex SHA-256 of the stored, re-encoded bytes.
pub sha256: CardBlobRefSha256,
///Size in bytes of the stored bytes.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub size: ::std::option::Option<::std::num::NonZeroU64>,
///Projection only: a URL the viewer can fetch the image from until `urlExpiresAt`.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub url: ::std::option::Option<::std::string::String>,
///Projection only: when `url` stops working.
#[serde(
rename = "urlExpiresAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub url_expires_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
}
impl CardBlobRef {
pub fn builder() -> builder::CardBlobRef {
Default::default()
}
}
///Media type of the stored bytes.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Media type of the stored bytes.",
/// "type": "string",
/// "enum": [
/// "image/png",
/// "image/jpeg",
/// "image/webp",
/// "image/avif"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum CardBlobRefMediaType {
#[serde(rename = "image/png")]
ImagePng,
#[serde(rename = "image/jpeg")]
ImageJpeg,
#[serde(rename = "image/webp")]
ImageWebp,
#[serde(rename = "image/avif")]
ImageAvif,
}
impl ::std::fmt::Display for CardBlobRefMediaType {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::ImagePng => f.write_str("image/png"),
Self::ImageJpeg => f.write_str("image/jpeg"),
Self::ImageWebp => f.write_str("image/webp"),
Self::ImageAvif => f.write_str("image/avif"),
}
}
}
impl ::std::str::FromStr for CardBlobRefMediaType {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"image/png" => Ok(Self::ImagePng),
"image/jpeg" => Ok(Self::ImageJpeg),
"image/webp" => Ok(Self::ImageWebp),
"image/avif" => Ok(Self::ImageAvif),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for CardBlobRefMediaType {
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 CardBlobRefMediaType {
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 CardBlobRefMediaType {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Lowercase hex SHA-256 of the stored, re-encoded bytes.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Lowercase hex SHA-256 of the stored, re-encoded bytes.",
/// "type": "string",
/// "pattern": "^[0-9a-f]{64}$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct CardBlobRefSha256(::std::string::String);
impl ::std::ops::Deref for CardBlobRefSha256 {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<CardBlobRefSha256> for ::std::string::String {
fn from(value: CardBlobRefSha256) -> Self {
value.0
}
}
impl ::std::str::FromStr for CardBlobRefSha256 {
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("^[0-9a-f]{64}$").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[0-9a-f]{64}$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for CardBlobRefSha256 {
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 CardBlobRefSha256 {
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 CardBlobRefSha256 {
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 CardBlobRefSha256 {
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())
})
}
}
///Opaque identifier of one directory entry: `dir_` followed by 16 to 64 base64url characters. Random, scoped to one community, and stable for the life of the membership — it survives a rotation of the member's DID, which is why groups, notes and cards are keyed by it. It MUST NOT be derived from, and MUST NOT reveal, any DID of the member, and the same person's entries in two communities MUST NOT share one. Compared by exact string equality.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "EntryId",
/// "description": "Opaque identifier of one directory entry: `dir_` followed by 16 to 64 base64url characters. Random, scoped to one community, and stable for the life of the membership — it survives a rotation of the member's DID, which is why groups, notes and cards are keyed by it. It MUST NOT be derived from, and MUST NOT reveal, any DID of the member, and the same person's entries in two communities MUST NOT share one. Compared by exact string equality.",
/// "type": "string",
/// "pattern": "^dir_[A-Za-z0-9_-]{16,64}$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct EntryId(::std::string::String);
impl ::std::ops::Deref for EntryId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<EntryId> for ::std::string::String {
fn from(value: EntryId) -> Self {
value.0
}
}
impl ::std::str::FromStr for EntryId {
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("^dir_[A-Za-z0-9_-]{16,64}$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^dir_[A-Za-z0-9_-]{16,64}$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for EntryId {
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 EntryId {
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 EntryId {
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 EntryId {
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())
})
}
}
///Identifier of a directory field. A key with no `.` is a BASE field, the same in every community: `displayName`, `nickname`, `avatar`, `pronouns`, `bio`, `links` (written by the member) and `role`, `joinedAt`, `did`, `personhood` (derived from the community's own records, never stored on a card). A community-defined field MUST use a reverse-DNS key (`org.example.employer`), so a base key never collides with one, and a key is never reused with a different meaning once defined.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "FieldKey",
/// "description": "Identifier of a directory field. A key with no `.` is a BASE field, the same in every community: `displayName`, `nickname`, `avatar`, `pronouns`, `bio`, `links` (written by the member) and `role`, `joinedAt`, `did`, `personhood` (derived from the community's own records, never stored on a card). A community-defined field MUST use a reverse-DNS key (`org.example.employer`), so a base key never collides with one, and a key is never reused with a different meaning once defined.",
/// "type": "string",
/// "maxLength": 128,
/// "minLength": 1,
/// "pattern": "^([a-z][a-z0-9-]*\\.)*[a-z][a-zA-Z0-9]{0,63}$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct FieldKey(::std::string::String);
impl ::std::ops::Deref for FieldKey {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<FieldKey> for ::std::string::String {
fn from(value: FieldKey) -> Self {
value.0
}
}
impl ::std::str::FromStr for FieldKey {
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());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^([a-z][a-z0-9-]*\\.)*[a-z][a-zA-Z0-9]{0,63}$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err(
"doesn't match pattern \"^([a-z][a-z0-9-]*\\.)*[a-z][a-zA-Z0-9]{0,63}$\"".into(),
);
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for FieldKey {
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 FieldKey {
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 FieldKey {
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 FieldKey {
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 value of one field. Which shape a field takes is fixed by its definition's `type`: text-like types (`text`, `longText`, `url`, `email`, `phone`, `enum`, `date` as YYYY-MM-DD, `country` as ISO 3166-1 alpha-2, `did`) are strings; `multiEnum` and the base field `links` are arrays of strings; `image` and the base field `avatar` are a `CardBlobRef`; `claim` is a `VerifiedValue`; the derived base field `personhood` is a boolean.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "FieldValue",
/// "description": "The value of one field. Which shape a field takes is fixed by its definition's `type`: text-like types (`text`, `longText`, `url`, `email`, `phone`, `enum`, `date` as YYYY-MM-DD, `country` as ISO 3166-1 alpha-2, `did`) are strings; `multiEnum` and the base field `links` are arrays of strings; `image` and the base field `avatar` are a `CardBlobRef`; `claim` is a `VerifiedValue`; the derived base field `personhood` is a boolean.",
/// "anyOf": [
/// {
/// "type": "string",
/// "maxLength": 2000
/// },
/// {
/// "type": "boolean"
/// },
/// {
/// "type": "array",
/// "items": {
/// "type": "string",
/// "maxLength": 500
/// },
/// "maxItems": 32
/// },
/// {
/// "$ref": "#/definitions/CardBlobRef"
/// },
/// {
/// "$ref": "#/definitions/VerifiedValue"
/// }
/// ]
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(untagged)]
#[non_exhaustive]
pub enum FieldValue {
String(FieldValueString),
Boolean(bool),
Array(::std::vec::Vec<FieldValueArrayItem>),
CardBlobRef(CardBlobRef),
VerifiedValue(VerifiedValue),
}
impl ::std::convert::From<FieldValueString> for FieldValue {
fn from(value: FieldValueString) -> Self {
Self::String(value)
}
}
impl ::std::convert::From<bool> for FieldValue {
fn from(value: bool) -> Self {
Self::Boolean(value)
}
}
impl ::std::convert::From<::std::vec::Vec<FieldValueArrayItem>> for FieldValue {
fn from(value: ::std::vec::Vec<FieldValueArrayItem>) -> Self {
Self::Array(value)
}
}
impl ::std::convert::From<CardBlobRef> for FieldValue {
fn from(value: CardBlobRef) -> Self {
Self::CardBlobRef(value)
}
}
impl ::std::convert::From<VerifiedValue> for FieldValue {
fn from(value: VerifiedValue) -> Self {
Self::VerifiedValue(value)
}
}
///`FieldValueArrayItem`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "maxLength": 500
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct FieldValueArrayItem(::std::string::String);
impl ::std::ops::Deref for FieldValueArrayItem {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<FieldValueArrayItem> for ::std::string::String {
fn from(value: FieldValueArrayItem) -> Self {
value.0
}
}
impl ::std::str::FromStr for FieldValueArrayItem {
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());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for FieldValueArrayItem {
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 FieldValueArrayItem {
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 FieldValueArrayItem {
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 FieldValueArrayItem {
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())
})
}
}
///`FieldValueString`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "maxLength": 2000
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct FieldValueString(::std::string::String);
impl ::std::ops::Deref for FieldValueString {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<FieldValueString> for ::std::string::String {
fn from(value: FieldValueString) -> Self {
value.0
}
}
impl ::std::str::FromStr for FieldValueString {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 2000usize {
return Err("longer than 2000 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for FieldValueString {
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 FieldValueString {
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 FieldValueString {
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 FieldValueString {
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())
})
}
}
///An administrator writes the values of admin-sourced directory fields on a member's card — the facts the community asserts about a member, which the member reads and cannot change. The outer document members are owned by the framework — SPEC §6.3.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "$id": "https://trusttasks.org/spec/vtc/directory/card/assert/0.1",
/// "title": "Payload",
/// "description": "An administrator writes the values of admin-sourced directory fields on a member's card — the facts the community asserts about a member, which the member reads and cannot change. The outer document members are owned by the framework — SPEC §6.3.",
/// "type": "object",
/// "required": [
/// "entryId",
/// "reason",
/// "values"
/// ],
/// "properties": {
/// "entryId": {
/// "$ref": "#/definitions/EntryId"
/// },
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "reason": {
/// "description": "Why, recorded with the change and shown to anyone who must approve it.",
/// "type": "string",
/// "maxLength": 1024,
/// "minLength": 1
/// },
/// "values": {
/// "description": "Values to set, keyed by `admin`-sourced field; `null` clears one.",
/// "type": "object",
/// "maxProperties": 64,
/// "minProperties": 1,
/// "additionalProperties": {
/// "anyOf": [
/// {
/// "$ref": "#/definitions/FieldValue"
/// },
/// {
/// "type": "null"
/// }
/// ]
/// },
/// "propertyNames": {
/// "$ref": "#/definitions/FieldKey"
/// }
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
#[serde(rename = "entryId")]
pub entry_id: EntryId,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///Why, recorded with the change and shown to anyone who must approve it.
pub reason: PayloadReason,
///Values to set, keyed by `admin`-sourced field; `null` clears one.
pub values: ::std::collections::HashMap<FieldKey, ::std::option::Option<FieldValue>>,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///Why, recorded with the change and shown to anyone who must approve it.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Why, recorded with the change and shown to anyone who must approve it.",
/// "type": "string",
/// "maxLength": 1024,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PayloadReason(::std::string::String);
impl ::std::ops::Deref for PayloadReason {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PayloadReason> for ::std::string::String {
fn from(value: PayloadReason) -> Self {
value.0
}
}
impl ::std::str::FromStr for PayloadReason {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 1024usize {
return Err("longer than 1024 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 PayloadReason {
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 PayloadReason {
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 PayloadReason {
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 PayloadReason {
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 success response to a vtc/directory/card/assert/0.1 request. Carried in a Trust Task document whose type is https://trusttasks.org/spec/vtc/directory/card/assert/0.1#response.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Response",
/// "description": "The success response to a vtc/directory/card/assert/0.1 request. Carried in a Trust Task document whose type is https://trusttasks.org/spec/vtc/directory/card/assert/0.1#response.",
/// "type": "object",
/// "required": [
/// "entryId",
/// "revision",
/// "written"
/// ],
/// "properties": {
/// "entryId": {
/// "$ref": "#/definitions/EntryId"
/// },
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "revision": {
/// "type": "integer",
/// "minimum": 0.0
/// },
/// "written": {
/// "description": "The fields written or cleared.",
/// "type": "array",
/// "items": {
/// "$ref": "#/definitions/FieldKey"
/// },
/// "maxItems": 64
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "response"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Response {
#[serde(rename = "entryId")]
pub entry_id: EntryId,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
pub revision: u64,
///The fields written or cleared.
pub written: ::std::vec::Vec<FieldKey>,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
///The value of a `credential`-sourced field: a claim the member disclosed from a credential they presented, with the issuer that attests it. A verified value always names its issuer, and a self-asserted value is never shaped as one. The community keeps only the disclosed claim and these facts about it — never the presentation.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "VerifiedValue",
/// "description": "The value of a `credential`-sourced field: a claim the member disclosed from a credential they presented, with the issuer that attests it. A verified value always names its issuer, and a self-asserted value is never shaped as one. The community keeps only the disclosed claim and these facts about it — never the presentation.",
/// "type": "object",
/// "required": [
/// "issuer",
/// "value",
/// "verifiedAt"
/// ],
/// "properties": {
/// "credentialType": {
/// "description": "The most specific `type` of the credential the claim came from.",
/// "type": "string",
/// "maxLength": 128,
/// "minLength": 1
/// },
/// "issuer": {
/// "description": "DID of the credential's issuer, shown as the field's verification badge.",
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
/// },
/// "validUntil": {
/// "description": "When the credential expires, where it does. The community withdraws the value once it passes.",
/// "type": "string",
/// "format": "date-time"
/// },
/// "value": {
/// "description": "The disclosed claim value.",
/// "anyOf": [
/// {
/// "type": "string",
/// "maxLength": 2000
/// },
/// {
/// "type": "boolean"
/// },
/// {
/// "type": "number"
/// }
/// ]
/// },
/// "verifiedAt": {
/// "description": "When the community verified the presentation.",
/// "type": "string",
/// "format": "date-time"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct VerifiedValue {
///The most specific `type` of the credential the claim came from.
#[serde(
rename = "credentialType",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub credential_type: ::std::option::Option<VerifiedValueCredentialType>,
///DID of the credential's issuer, shown as the field's verification badge.
pub issuer: VerifiedValueIssuer,
///When the credential expires, where it does. The community withdraws the value once it passes.
#[serde(
rename = "validUntil",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub valid_until: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
///The disclosed claim value.
pub value: VerifiedValueValue,
///When the community verified the presentation.
#[serde(rename = "verifiedAt")]
pub verified_at: ::chrono::DateTime<::chrono::offset::Utc>,
}
impl VerifiedValue {
pub fn builder() -> builder::VerifiedValue {
Default::default()
}
}
///The most specific `type` of the credential the claim came from.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The most specific `type` of the credential the claim came from.",
/// "type": "string",
/// "maxLength": 128,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct VerifiedValueCredentialType(::std::string::String);
impl ::std::ops::Deref for VerifiedValueCredentialType {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<VerifiedValueCredentialType> for ::std::string::String {
fn from(value: VerifiedValueCredentialType) -> Self {
value.0
}
}
impl ::std::str::FromStr for VerifiedValueCredentialType {
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 VerifiedValueCredentialType {
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 VerifiedValueCredentialType {
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 VerifiedValueCredentialType {
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 VerifiedValueCredentialType {
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())
})
}
}
///DID of the credential's issuer, shown as the field's verification badge.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "DID of the credential's issuer, shown as the field's verification badge.",
/// "type": "string",
/// "maxLength": 2048,
/// "pattern": "^did:"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct VerifiedValueIssuer(::std::string::String);
impl ::std::ops::Deref for VerifiedValueIssuer {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<VerifiedValueIssuer> for ::std::string::String {
fn from(value: VerifiedValueIssuer) -> Self {
value.0
}
}
impl ::std::str::FromStr for VerifiedValueIssuer {
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 VerifiedValueIssuer {
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 VerifiedValueIssuer {
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 VerifiedValueIssuer {
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 VerifiedValueIssuer {
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 disclosed claim value.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The disclosed claim value.",
/// "anyOf": [
/// {
/// "type": "string",
/// "maxLength": 2000
/// },
/// {
/// "type": "boolean"
/// },
/// {
/// "type": "number"
/// }
/// ]
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(untagged)]
#[non_exhaustive]
pub enum VerifiedValueValue {
String(VerifiedValueValueString),
Boolean(bool),
Number(f64),
}
impl ::std::str::FromStr for VerifiedValueValue {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if let Ok(v) = value.parse() {
Ok(Self::String(v))
} else if let Ok(v) = value.parse() {
Ok(Self::Boolean(v))
} else if let Ok(v) = value.parse() {
Ok(Self::Number(v))
} else {
Err("string conversion failed for all variants".into())
}
}
}
impl ::std::convert::TryFrom<&str> for VerifiedValueValue {
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 VerifiedValueValue {
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 VerifiedValueValue {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::fmt::Display for VerifiedValueValue {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match self {
Self::String(x) => x.fmt(f),
Self::Boolean(x) => x.fmt(f),
Self::Number(x) => x.fmt(f),
}
}
}
impl ::std::convert::From<VerifiedValueValueString> for VerifiedValueValue {
fn from(value: VerifiedValueValueString) -> Self {
Self::String(value)
}
}
impl ::std::convert::From<bool> for VerifiedValueValue {
fn from(value: bool) -> Self {
Self::Boolean(value)
}
}
impl ::std::convert::From<f64> for VerifiedValueValue {
fn from(value: f64) -> Self {
Self::Number(value)
}
}
///`VerifiedValueValueString`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "maxLength": 2000
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct VerifiedValueValueString(::std::string::String);
impl ::std::ops::Deref for VerifiedValueValueString {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<VerifiedValueValueString> for ::std::string::String {
fn from(value: VerifiedValueValueString) -> Self {
value.0
}
}
impl ::std::str::FromStr for VerifiedValueValueString {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 2000usize {
return Err("longer than 2000 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for VerifiedValueValueString {
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 VerifiedValueValueString {
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 VerifiedValueValueString {
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 VerifiedValueValueString {
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())
})
}
}
/// Types for composing complex structures.
pub mod builder {
#[derive(Clone, Debug)]
pub struct CardBlobRef {
media_type: ::std::result::Result<super::CardBlobRefMediaType, ::std::string::String>,
sha256: ::std::result::Result<super::CardBlobRefSha256, ::std::string::String>,
size: ::std::result::Result<
::std::option::Option<::std::num::NonZeroU64>,
::std::string::String,
>,
url: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
url_expires_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
}
impl ::std::default::Default for CardBlobRef {
fn default() -> Self {
Self {
media_type: Err("no value supplied for media_type".to_string()),
sha256: Err("no value supplied for sha256".to_string()),
size: Ok(Default::default()),
url: Ok(Default::default()),
url_expires_at: Ok(Default::default()),
}
}
}
impl CardBlobRef {
pub fn media_type<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::CardBlobRefMediaType>,
T::Error: ::std::fmt::Display,
{
self.media_type = value
.try_into()
.map_err(|e| format!("error converting supplied value for media_type: {e}"));
self
}
pub fn sha256<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::CardBlobRefSha256>,
T::Error: ::std::fmt::Display,
{
self.sha256 = value
.try_into()
.map_err(|e| format!("error converting supplied value for sha256: {e}"));
self
}
pub fn size<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::num::NonZeroU64>>,
T::Error: ::std::fmt::Display,
{
self.size = value
.try_into()
.map_err(|e| format!("error converting supplied value for size: {e}"));
self
}
pub fn url<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.url = value
.try_into()
.map_err(|e| format!("error converting supplied value for url: {e}"));
self
}
pub fn url_expires_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.url_expires_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for url_expires_at: {e}"));
self
}
}
impl ::std::convert::TryFrom<CardBlobRef> for super::CardBlobRef {
type Error = super::error::ConversionError;
fn try_from(
value: CardBlobRef,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
media_type: value.media_type?,
sha256: value.sha256?,
size: value.size?,
url: value.url?,
url_expires_at: value.url_expires_at?,
})
}
}
impl ::std::convert::From<super::CardBlobRef> for CardBlobRef {
fn from(value: super::CardBlobRef) -> Self {
Self {
media_type: Ok(value.media_type),
sha256: Ok(value.sha256),
size: Ok(value.size),
url: Ok(value.url),
url_expires_at: Ok(value.url_expires_at),
}
}
}
#[derive(Clone, Debug)]
pub struct Payload {
entry_id: ::std::result::Result<super::EntryId, ::std::string::String>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
reason: ::std::result::Result<super::PayloadReason, ::std::string::String>,
values: ::std::result::Result<
::std::collections::HashMap<super::FieldKey, ::std::option::Option<super::FieldValue>>,
::std::string::String,
>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
entry_id: Err("no value supplied for entry_id".to_string()),
ext: Ok(Default::default()),
reason: Err("no value supplied for reason".to_string()),
values: Err("no value supplied for values".to_string()),
}
}
}
impl Payload {
pub fn entry_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::EntryId>,
T::Error: ::std::fmt::Display,
{
self.entry_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for entry_id: {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 reason<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PayloadReason>,
T::Error: ::std::fmt::Display,
{
self.reason = value
.try_into()
.map_err(|e| format!("error converting supplied value for reason: {e}"));
self
}
pub fn values<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<
::std::collections::HashMap<
super::FieldKey,
::std::option::Option<super::FieldValue>,
>,
>,
T::Error: ::std::fmt::Display,
{
self.values = value
.try_into()
.map_err(|e| format!("error converting supplied value for values: {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 {
entry_id: value.entry_id?,
ext: value.ext?,
reason: value.reason?,
values: value.values?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
entry_id: Ok(value.entry_id),
ext: Ok(value.ext),
reason: Ok(value.reason),
values: Ok(value.values),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
entry_id: ::std::result::Result<super::EntryId, ::std::string::String>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
revision: ::std::result::Result<u64, ::std::string::String>,
written: ::std::result::Result<::std::vec::Vec<super::FieldKey>, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
entry_id: Err("no value supplied for entry_id".to_string()),
ext: Ok(Default::default()),
revision: Err("no value supplied for revision".to_string()),
written: Err("no value supplied for written".to_string()),
}
}
}
impl Response {
pub fn entry_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::EntryId>,
T::Error: ::std::fmt::Display,
{
self.entry_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for entry_id: {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 revision<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<u64>,
T::Error: ::std::fmt::Display,
{
self.revision = value
.try_into()
.map_err(|e| format!("error converting supplied value for revision: {e}"));
self
}
pub fn written<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::vec::Vec<super::FieldKey>>,
T::Error: ::std::fmt::Display,
{
self.written = value
.try_into()
.map_err(|e| format!("error converting supplied value for written: {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 {
entry_id: value.entry_id?,
ext: value.ext?,
revision: value.revision?,
written: value.written?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
entry_id: Ok(value.entry_id),
ext: Ok(value.ext),
revision: Ok(value.revision),
written: Ok(value.written),
}
}
}
#[derive(Clone, Debug)]
pub struct VerifiedValue {
credential_type: ::std::result::Result<
::std::option::Option<super::VerifiedValueCredentialType>,
::std::string::String,
>,
issuer: ::std::result::Result<super::VerifiedValueIssuer, ::std::string::String>,
valid_until: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
value: ::std::result::Result<super::VerifiedValueValue, ::std::string::String>,
verified_at:
::std::result::Result<::chrono::DateTime<::chrono::offset::Utc>, ::std::string::String>,
}
impl ::std::default::Default for VerifiedValue {
fn default() -> Self {
Self {
credential_type: Ok(Default::default()),
issuer: Err("no value supplied for issuer".to_string()),
valid_until: Ok(Default::default()),
value: Err("no value supplied for value".to_string()),
verified_at: Err("no value supplied for verified_at".to_string()),
}
}
}
impl VerifiedValue {
pub fn credential_type<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::VerifiedValueCredentialType>>,
T::Error: ::std::fmt::Display,
{
self.credential_type = value
.try_into()
.map_err(|e| format!("error converting supplied value for credential_type: {e}"));
self
}
pub fn issuer<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::VerifiedValueIssuer>,
T::Error: ::std::fmt::Display,
{
self.issuer = value
.try_into()
.map_err(|e| format!("error converting supplied value for issuer: {e}"));
self
}
pub fn 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.valid_until = value
.try_into()
.map_err(|e| format!("error converting supplied value for valid_until: {e}"));
self
}
pub fn value<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::VerifiedValueValue>,
T::Error: ::std::fmt::Display,
{
self.value = value
.try_into()
.map_err(|e| format!("error converting supplied value for value: {e}"));
self
}
pub fn verified_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::chrono::DateTime<::chrono::offset::Utc>>,
T::Error: ::std::fmt::Display,
{
self.verified_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for verified_at: {e}"));
self
}
}
impl ::std::convert::TryFrom<VerifiedValue> for super::VerifiedValue {
type Error = super::error::ConversionError;
fn try_from(
value: VerifiedValue,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
credential_type: value.credential_type?,
issuer: value.issuer?,
valid_until: value.valid_until?,
value: value.value?,
verified_at: value.verified_at?,
})
}
}
impl ::std::convert::From<super::VerifiedValue> for VerifiedValue {
fn from(value: super::VerifiedValue) -> Self {
Self {
credential_type: Ok(value.credential_type),
issuer: Ok(value.issuer),
valid_until: Ok(value.valid_until),
value: Ok(value.value),
verified_at: Ok(value.verified_at),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vtc/directory/card/assert/0.1";
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 \"CardBlobRef\": {\n \"additionalProperties\": false,\n \"description\": \"A content-addressed image held in the community's blob store — an avatar or an `image` field. At most 256 KiB, images only, re-encoded by the community on upload (vtc/directory/images/upload: metadata stripped, dimensions capped) so its digest does not link the member across communities. A viewer reads the bytes with vtc/directory/images/get, which answers only where the same projection shows the value. `url` and `urlExpiresAt` MAY appear in a projection: a short-lived URL the community checks against the same projection, so a member-only image is never a public URL. A community that does not offer one leaves both out.\",\n \"properties\": {\n \"mediaType\": {\n \"description\": \"Media type of the stored bytes.\",\n \"enum\": [\n \"image/png\",\n \"image/jpeg\",\n \"image/webp\",\n \"image/avif\"\n ],\n \"type\": \"string\"\n },\n \"sha256\": {\n \"description\": \"Lowercase hex SHA-256 of the stored, re-encoded bytes.\",\n \"pattern\": \"^[0-9a-f]{64}$\",\n \"type\": \"string\"\n },\n \"size\": {\n \"description\": \"Size in bytes of the stored bytes.\",\n \"maximum\": 262144,\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"url\": {\n \"description\": \"Projection only: a URL the viewer can fetch the image from until `urlExpiresAt`.\",\n \"format\": \"uri\",\n \"maxLength\": 2048,\n \"type\": \"string\"\n },\n \"urlExpiresAt\": {\n \"description\": \"Projection only: when `url` stops working.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"sha256\",\n \"mediaType\"\n ],\n \"title\": \"CardBlobRef\",\n \"type\": \"object\"\n },\n \"EntryId\": {\n \"description\": \"Opaque identifier of one directory entry: `dir_` followed by 16 to 64 base64url characters. Random, scoped to one community, and stable for the life of the membership — it survives a rotation of the member's DID, which is why groups, notes and cards are keyed by it. It MUST NOT be derived from, and MUST NOT reveal, any DID of the member, and the same person's entries in two communities MUST NOT share one. Compared by exact string equality.\",\n \"pattern\": \"^dir_[A-Za-z0-9_-]{16,64}$\",\n \"title\": \"EntryId\",\n \"type\": \"string\"\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 \"FieldKey\": {\n \"description\": \"Identifier of a directory field. A key with no `.` is a BASE field, the same in every community: `displayName`, `nickname`, `avatar`, `pronouns`, `bio`, `links` (written by the member) and `role`, `joinedAt`, `did`, `personhood` (derived from the community's own records, never stored on a card). A community-defined field MUST use a reverse-DNS key (`org.example.employer`), so a base key never collides with one, and a key is never reused with a different meaning once defined.\",\n \"maxLength\": 128,\n \"minLength\": 1,\n \"pattern\": \"^([a-z][a-z0-9-]*\\\\.)*[a-z][a-zA-Z0-9]{0,63}$\",\n \"title\": \"FieldKey\",\n \"type\": \"string\"\n },\n \"FieldValue\": {\n \"anyOf\": [\n {\n \"maxLength\": 2000,\n \"type\": \"string\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"items\": {\n \"maxLength\": 500,\n \"type\": \"string\"\n },\n \"maxItems\": 32,\n \"type\": \"array\"\n },\n {\n \"$ref\": \"#/$defs/CardBlobRef\"\n },\n {\n \"$ref\": \"#/$defs/VerifiedValue\"\n }\n ],\n \"description\": \"The value of one field. Which shape a field takes is fixed by its definition's `type`: text-like types (`text`, `longText`, `url`, `email`, `phone`, `enum`, `date` as YYYY-MM-DD, `country` as ISO 3166-1 alpha-2, `did`) are strings; `multiEnum` and the base field `links` are arrays of strings; `image` and the base field `avatar` are a `CardBlobRef`; `claim` is a `VerifiedValue`; the derived base field `personhood` is a boolean.\",\n \"title\": \"FieldValue\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"The success response to a vtc/directory/card/assert/0.1 request. Carried in a Trust Task document whose type is https://trusttasks.org/spec/vtc/directory/card/assert/0.1#response.\",\n \"properties\": {\n \"entryId\": {\n \"$ref\": \"#/$defs/EntryId\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"revision\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"written\": {\n \"description\": \"The fields written or cleared.\",\n \"items\": {\n \"$ref\": \"#/$defs/FieldKey\"\n },\n \"maxItems\": 64,\n \"type\": \"array\"\n }\n },\n \"required\": [\n \"entryId\",\n \"written\",\n \"revision\"\n ],\n \"title\": \"VTC Directory — Card — Assert — response payload\",\n \"type\": \"object\"\n },\n \"VerifiedValue\": {\n \"additionalProperties\": false,\n \"description\": \"The value of a `credential`-sourced field: a claim the member disclosed from a credential they presented, with the issuer that attests it. A verified value always names its issuer, and a self-asserted value is never shaped as one. The community keeps only the disclosed claim and these facts about it — never the presentation.\",\n \"properties\": {\n \"credentialType\": {\n \"description\": \"The most specific `type` of the credential the claim came from.\",\n \"maxLength\": 128,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"issuer\": {\n \"description\": \"DID of the credential's issuer, shown as the field's verification badge.\",\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"validUntil\": {\n \"description\": \"When the credential expires, where it does. The community withdraws the value once it passes.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"value\": {\n \"anyOf\": [\n {\n \"maxLength\": 2000,\n \"type\": \"string\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"number\"\n }\n ],\n \"description\": \"The disclosed claim value.\"\n },\n \"verifiedAt\": {\n \"description\": \"When the community verified the presentation.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"value\",\n \"issuer\",\n \"verifiedAt\"\n ],\n \"title\": \"VerifiedValue\",\n \"type\": \"object\"\n }\n },\n \"$id\": \"https://trusttasks.org/spec/vtc/directory/card/assert/0.1\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"additionalProperties\": false,\n \"description\": \"An administrator writes the values of admin-sourced directory fields on a member's card — the facts the community asserts about a member, which the member reads and cannot change. The outer document members are owned by the framework — SPEC §6.3.\",\n \"properties\": {\n \"entryId\": {\n \"$ref\": \"#/$defs/EntryId\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"reason\": {\n \"description\": \"Why, recorded with the change and shown to anyone who must approve it.\",\n \"maxLength\": 1024,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"values\": {\n \"additionalProperties\": {\n \"anyOf\": [\n {\n \"$ref\": \"#/$defs/FieldValue\"\n },\n {\n \"type\": \"null\"\n }\n ]\n },\n \"description\": \"Values to set, keyed by `admin`-sourced field; `null` clears one.\",\n \"maxProperties\": 64,\n \"minProperties\": 1,\n \"propertyNames\": {\n \"$ref\": \"#/$defs/FieldKey\"\n },\n \"type\": \"object\"\n }\n },\n \"required\": [\n \"entryId\",\n \"values\",\n \"reason\"\n ],\n \"title\": \"VTC Directory — Card — Assert — payload\",\n \"type\": \"object\"\n}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str =
"https://trusttasks.org/spec/vtc/directory/card/assert/0.1#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 \"CardBlobRef\": {\n \"additionalProperties\": false,\n \"description\": \"A content-addressed image held in the community's blob store — an avatar or an `image` field. At most 256 KiB, images only, re-encoded by the community on upload (vtc/directory/images/upload: metadata stripped, dimensions capped) so its digest does not link the member across communities. A viewer reads the bytes with vtc/directory/images/get, which answers only where the same projection shows the value. `url` and `urlExpiresAt` MAY appear in a projection: a short-lived URL the community checks against the same projection, so a member-only image is never a public URL. A community that does not offer one leaves both out.\",\n \"properties\": {\n \"mediaType\": {\n \"description\": \"Media type of the stored bytes.\",\n \"enum\": [\n \"image/png\",\n \"image/jpeg\",\n \"image/webp\",\n \"image/avif\"\n ],\n \"type\": \"string\"\n },\n \"sha256\": {\n \"description\": \"Lowercase hex SHA-256 of the stored, re-encoded bytes.\",\n \"pattern\": \"^[0-9a-f]{64}$\",\n \"type\": \"string\"\n },\n \"size\": {\n \"description\": \"Size in bytes of the stored bytes.\",\n \"maximum\": 262144,\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"url\": {\n \"description\": \"Projection only: a URL the viewer can fetch the image from until `urlExpiresAt`.\",\n \"format\": \"uri\",\n \"maxLength\": 2048,\n \"type\": \"string\"\n },\n \"urlExpiresAt\": {\n \"description\": \"Projection only: when `url` stops working.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"sha256\",\n \"mediaType\"\n ],\n \"title\": \"CardBlobRef\",\n \"type\": \"object\"\n },\n \"EntryId\": {\n \"description\": \"Opaque identifier of one directory entry: `dir_` followed by 16 to 64 base64url characters. Random, scoped to one community, and stable for the life of the membership — it survives a rotation of the member's DID, which is why groups, notes and cards are keyed by it. It MUST NOT be derived from, and MUST NOT reveal, any DID of the member, and the same person's entries in two communities MUST NOT share one. Compared by exact string equality.\",\n \"pattern\": \"^dir_[A-Za-z0-9_-]{16,64}$\",\n \"title\": \"EntryId\",\n \"type\": \"string\"\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 \"FieldKey\": {\n \"description\": \"Identifier of a directory field. A key with no `.` is a BASE field, the same in every community: `displayName`, `nickname`, `avatar`, `pronouns`, `bio`, `links` (written by the member) and `role`, `joinedAt`, `did`, `personhood` (derived from the community's own records, never stored on a card). A community-defined field MUST use a reverse-DNS key (`org.example.employer`), so a base key never collides with one, and a key is never reused with a different meaning once defined.\",\n \"maxLength\": 128,\n \"minLength\": 1,\n \"pattern\": \"^([a-z][a-z0-9-]*\\\\.)*[a-z][a-zA-Z0-9]{0,63}$\",\n \"title\": \"FieldKey\",\n \"type\": \"string\"\n },\n \"FieldValue\": {\n \"anyOf\": [\n {\n \"maxLength\": 2000,\n \"type\": \"string\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"items\": {\n \"maxLength\": 500,\n \"type\": \"string\"\n },\n \"maxItems\": 32,\n \"type\": \"array\"\n },\n {\n \"$ref\": \"#/$defs/CardBlobRef\"\n },\n {\n \"$ref\": \"#/$defs/VerifiedValue\"\n }\n ],\n \"description\": \"The value of one field. Which shape a field takes is fixed by its definition's `type`: text-like types (`text`, `longText`, `url`, `email`, `phone`, `enum`, `date` as YYYY-MM-DD, `country` as ISO 3166-1 alpha-2, `did`) are strings; `multiEnum` and the base field `links` are arrays of strings; `image` and the base field `avatar` are a `CardBlobRef`; `claim` is a `VerifiedValue`; the derived base field `personhood` is a boolean.\",\n \"title\": \"FieldValue\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"The success response to a vtc/directory/card/assert/0.1 request. Carried in a Trust Task document whose type is https://trusttasks.org/spec/vtc/directory/card/assert/0.1#response.\",\n \"properties\": {\n \"entryId\": {\n \"$ref\": \"#/$defs/EntryId\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"revision\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"written\": {\n \"description\": \"The fields written or cleared.\",\n \"items\": {\n \"$ref\": \"#/$defs/FieldKey\"\n },\n \"maxItems\": 64,\n \"type\": \"array\"\n }\n },\n \"required\": [\n \"entryId\",\n \"written\",\n \"revision\"\n ],\n \"title\": \"VTC Directory — Card — Assert — response payload\",\n \"type\": \"object\"\n },\n \"VerifiedValue\": {\n \"additionalProperties\": false,\n \"description\": \"The value of a `credential`-sourced field: a claim the member disclosed from a credential they presented, with the issuer that attests it. A verified value always names its issuer, and a self-asserted value is never shaped as one. The community keeps only the disclosed claim and these facts about it — never the presentation.\",\n \"properties\": {\n \"credentialType\": {\n \"description\": \"The most specific `type` of the credential the claim came from.\",\n \"maxLength\": 128,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"issuer\": {\n \"description\": \"DID of the credential's issuer, shown as the field's verification badge.\",\n \"maxLength\": 2048,\n \"pattern\": \"^did:\",\n \"type\": \"string\"\n },\n \"validUntil\": {\n \"description\": \"When the credential expires, where it does. The community withdraws the value once it passes.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"value\": {\n \"anyOf\": [\n {\n \"maxLength\": 2000,\n \"type\": \"string\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"number\"\n }\n ],\n \"description\": \"The disclosed claim value.\"\n },\n \"verifiedAt\": {\n \"description\": \"When the community verified the presentation.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"value\",\n \"issuer\",\n \"verifiedAt\"\n ],\n \"title\": \"VerifiedValue\",\n \"type\": \"object\"\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::NOT_FOUND,
error_codes::FIELD_UNKNOWN,
error_codes::FIELD_RETIRED,
error_codes::FIELD_NOT_WRITABLE,
error_codes::VALUE_INVALID,
error_codes::VALUE_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/directory/card/assert:notFound`
///
/// No active member has this entry.
///
/// Declared `retryable: false`.
pub const NOT_FOUND: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/directory/card/assert:notFound",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `vtc/directory/card/assert:fieldUnknown`
///
/// A value names a field the schema does not have.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const FIELD_UNKNOWN: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/directory/card/assert:fieldUnknown",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"field\":{\"maxLength\":128,\"type\":\"string\"}},\"required\":[\"field\"],\"type\":\"object\"}",
),
};
/// `vtc/directory/card/assert:fieldRetired`
///
/// A value names a retired or disabled field.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const FIELD_RETIRED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/directory/card/assert:fieldRetired",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"field\":{\"maxLength\":128,\"type\":\"string\"}},\"required\":[\"field\"],\"type\":\"object\"}",
),
};
/// `vtc/directory/card/assert:fieldNotWritable`
///
/// A value names a field that is not `admin`-sourced.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const FIELD_NOT_WRITABLE: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/directory/card/assert:fieldNotWritable",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"field\":{\"maxLength\":128,\"type\":\"string\"}},\"required\":[\"field\"],\"type\":\"object\"}",
),
};
/// `vtc/directory/card/assert:valueInvalid`
///
/// A value does not fit its field's type or constraints.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const VALUE_INVALID: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/directory/card/assert:valueInvalid",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"field\":{\"maxLength\":128,\"type\":\"string\"},\"reason\":{\"maxLength\":500,\"type\":\"string\"}},\"required\":[\"field\"],\"type\":\"object\"}",
),
};
/// `vtc/directory/card/assert:valueRefused`
///
/// The community's directory policy refused the assertion.
///
/// Declared `retryable: false`.
/// Declares a `detailsSchema` for the error's `details` member.
pub const VALUE_REFUSED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "vtc/directory/card/assert:valueRefused",
retryable: false,
details_schema: ::core::option::Option::Some(
"{\"additionalProperties\":false,\"properties\":{\"field\":{\"maxLength\":128,\"type\":\"string\"},\"message\":{\"maxLength\":500,\"type\":\"string\"}},\"type\":\"object\"}",
),
};
}