//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `auth/oob/cancel`. 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())
}
}
}
///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())
})
}
}
///The starter or the lock holder ends an out-of-band request. Issued and signed by the starter key or by the lock key. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, parentThreadId, proof) are owned by the framework — SPEC §6.3.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "$id": "https://trusttasks.org/spec/auth/oob/cancel/0.1",
/// "title": "Payload",
/// "description": "The starter or the lock holder ends an out-of-band request. Issued and signed by the starter key or by the lock key. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, parentThreadId, proof) are owned by the framework — SPEC §6.3.",
/// "type": "object",
/// "required": [
/// "requestId"
/// ],
/// "properties": {
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "requestId": {
/// "$ref": "#/definitions/RequestId"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
#[serde(rename = "requestId")]
pub request_id: RequestId,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///The service-generated handle of one request: 16 to 32 bytes from a cryptographically secure random source, written as unpadded base64url (22 to 43 characters; 16 bytes, 22 characters, is RECOMMENDED). It is also the nonce of the exchange, so the family needs no separate challenge, and it is the `_id` of the trigger link (VTI-LNK-033). Compared as a string. It confers no authority on its holder.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "RequestId",
/// "description": "The service-generated handle of one request: 16 to 32 bytes from a cryptographically secure random source, written as unpadded base64url (22 to 43 characters; 16 bytes, 22 characters, is RECOMMENDED). It is also the nonce of the exchange, so the family needs no separate challenge, and it is the `_id` of the trigger link (VTI-LNK-033). Compared as a string. It confers no authority on its holder.",
/// "type": "string",
/// "maxLength": 43,
/// "minLength": 22,
/// "pattern": "^[A-Za-z0-9_-]{22,43}$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct RequestId(::std::string::String);
impl ::std::ops::Deref for RequestId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<RequestId> for ::std::string::String {
fn from(value: RequestId) -> Self {
value.0
}
}
impl ::std::str::FromStr for RequestId {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 43usize {
return Err("longer than 43 characters".into());
}
if value.chars().count() < 22usize {
return Err("shorter than 22 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^[A-Za-z0-9_-]{22,43}$").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[A-Za-z0-9_-]{22,43}$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for RequestId {
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 RequestId {
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 RequestId {
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 RequestId {
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())
})
}
}
///Confirms the request is cancelled. Cancelling an already-cancelled request answers the same way.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Response",
/// "description": "Confirms the request is cancelled. Cancelling an already-cancelled request answers the same way.",
/// "type": "object",
/// "required": [
/// "status"
/// ],
/// "properties": {
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "status": {
/// "description": "The request's final state.",
/// "type": "string",
/// "enum": [
/// "cancelled"
/// ]
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "response"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Response {
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///The request's final state.
pub status: ResponseStatus,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
///The request's final state.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The request's final state.",
/// "type": "string",
/// "enum": [
/// "cancelled"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ResponseStatus {
#[serde(rename = "cancelled")]
Cancelled,
}
impl ::std::fmt::Display for ResponseStatus {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Cancelled => f.write_str("cancelled"),
}
}
}
impl ::std::str::FromStr for ResponseStatus {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"cancelled" => Ok(Self::Cancelled),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ResponseStatus {
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 ResponseStatus {
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 ResponseStatus {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
/// Types for composing complex structures.
pub mod builder {
#[derive(Clone, Debug)]
pub struct Payload {
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
request_id: ::std::result::Result<super::RequestId, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
ext: Ok(Default::default()),
request_id: Err("no value supplied for request_id".to_string()),
}
}
}
impl Payload {
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 request_id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::RequestId>,
T::Error: ::std::fmt::Display,
{
self.request_id = value
.try_into()
.map_err(|e| format!("error converting supplied value for request_id: {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 {
ext: value.ext?,
request_id: value.request_id?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
ext: Ok(value.ext),
request_id: Ok(value.request_id),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
status: ::std::result::Result<super::ResponseStatus, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
ext: Ok(Default::default()),
status: Err("no value supplied for status".to_string()),
}
}
}
impl Response {
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn status<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseStatus>,
T::Error: ::std::fmt::Display,
{
self.status = value
.try_into()
.map_err(|e| format!("error converting supplied value for status: {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?,
status: value.status?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
ext: Ok(value.ext),
status: Ok(value.status),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/auth/oob/cancel/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 \"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 \"RequestId\": {\n \"description\": \"The service-generated handle of one request: 16 to 32 bytes from a cryptographically secure random source, written as unpadded base64url (22 to 43 characters; 16 bytes, 22 characters, is RECOMMENDED). It is also the nonce of the exchange, so the family needs no separate challenge, and it is the `_id` of the trigger link (VTI-LNK-033). Compared as a string. It confers no authority on its holder.\",\n \"maxLength\": 43,\n \"minLength\": 22,\n \"pattern\": \"^[A-Za-z0-9_-]{22,43}$\",\n \"title\": \"RequestId\",\n \"type\": \"string\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"Confirms the request is cancelled. Cancelling an already-cancelled request answers the same way.\",\n \"properties\": {\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"status\": {\n \"description\": \"The request's final state.\",\n \"enum\": [\n \"cancelled\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"status\"\n ],\n \"title\": \"Auth — OOB Cancel — response payload\",\n \"type\": \"object\"\n }\n },\n \"$id\": \"https://trusttasks.org/spec/auth/oob/cancel/0.1\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"additionalProperties\": false,\n \"description\": \"The starter or the lock holder ends an out-of-band request. Issued and signed by the starter key or by the lock key. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, parentThreadId, proof) are owned by the framework — SPEC §6.3.\",\n \"properties\": {\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"requestId\": {\n \"$ref\": \"#/$defs/RequestId\"\n }\n },\n \"required\": [\n \"requestId\"\n ],\n \"title\": \"Auth — OOB Cancel — payload\",\n \"type\": \"object\"\n}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/auth/oob/cancel/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 \"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 \"RequestId\": {\n \"description\": \"The service-generated handle of one request: 16 to 32 bytes from a cryptographically secure random source, written as unpadded base64url (22 to 43 characters; 16 bytes, 22 characters, is RECOMMENDED). It is also the nonce of the exchange, so the family needs no separate challenge, and it is the `_id` of the trigger link (VTI-LNK-033). Compared as a string. It confers no authority on its holder.\",\n \"maxLength\": 43,\n \"minLength\": 22,\n \"pattern\": \"^[A-Za-z0-9_-]{22,43}$\",\n \"title\": \"RequestId\",\n \"type\": \"string\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"Confirms the request is cancelled. Cancelling an already-cancelled request answers the same way.\",\n \"properties\": {\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"status\": {\n \"description\": \"The request's final state.\",\n \"enum\": [\n \"cancelled\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"status\"\n ],\n \"title\": \"Auth — OOB Cancel — response payload\",\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::REQUEST_NOT_FOUND,
error_codes::REQUEST_EXPIRED,
error_codes::ALREADY_DECIDED,
error_codes::NOT_AUTHORIZED,
];
/// 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 {
/// `auth/oob:requestNotFound`
///
/// No request has this `requestId`.
///
/// Declared `retryable: false`.
pub const REQUEST_NOT_FOUND: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "auth/oob:requestNotFound",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `auth/oob:requestExpired`
///
/// The request has expired or was already consumed.
///
/// Declared `retryable: false`.
pub const REQUEST_EXPIRED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "auth/oob:requestExpired",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `auth/oob:alreadyDecided`
///
/// The request has already been approved or declined.
///
/// Declared `retryable: false`.
pub const ALREADY_DECIDED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "auth/oob:alreadyDecided",
retryable: false,
details_schema: ::core::option::Option::None,
};
/// `auth/oob:notAuthorized`
///
/// The cancel is signed by neither the starter key nor the lock key.
///
/// Declared `retryable: false`.
pub const NOT_AUTHORIZED: crate::DeclaredErrorCode = crate::DeclaredErrorCode {
code: "auth/oob:notAuthorized",
retryable: false,
details_schema: ::core::option::Option::None,
};
}