//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `trust-task-control`. 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())
}
}
}
/**
The task-control request defined at SPEC.md §12: a producer withdrawing, pausing, or resuming work a consumer has already accepted.
This is a REQUEST, not a response. A consumer that stops work on its own initiative does not send one of these — it returns a trust-task-error carrying `cancelled`, so that a withdrawal and a refusal remain distinguishable to every party and to any auditor reading the retained documents afterwards.
The operation takes effect through SPEC.md §7.2 item 12: a valid, authorized control operation is one of the conditions a consumer re-evaluates immediately before each irreversible or externally visible effect. There is no separate race protocol.*/
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "$id": "https://trusttasks.org/spec/trust-task-control/0.1",
/// "title": "Payload",
/// "description": "\nThe task-control request defined at SPEC.md §12: a producer withdrawing, pausing, or resuming work a consumer has already accepted.\n\nThis is a REQUEST, not a response. A consumer that stops work on its own initiative does not send one of these — it returns a trust-task-error carrying `cancelled`, so that a withdrawal and a refusal remain distinguishable to every party and to any auditor reading the retained documents afterwards.\n\nThe operation takes effect through SPEC.md §7.2 item 12: a valid, authorized control operation is one of the conditions a consumer re-evaluates immediately before each irreversible or externally visible effect. There is no separate race protocol.",
/// "type": "object",
/// "required": [
/// "operation",
/// "target"
/// ],
/// "properties": {
/// "ext": {
/// "description": "Vendor-namespaced extension data per SPEC.md §4.5.1. Every immediate child key MUST be a reverse-DNS prefix the producer controls.",
/// "type": "object"
/// },
/// "operation": {
/// "description": "\nThe control operation requested.\n\n`cancel` stops the task permanently: it is terminal, and a cancelled task MUST NOT be resumed, retried, or cancelled again (SPEC.md §12.3). `suspend` halts further effects while preserving the consumer's current execution state — it does not undo work already performed. `resume` continues a suspended task from the state the consumer holds; a consumer MUST NOT resume after the target document's `expiresAt` (SPEC.md §12.5).\n\nThis is a discriminating field. A consumer that does not recognize a value MUST reject the document rather than apply a default — silently downgrading an unrecognized operation to a known one would let a producer's intent be replaced by the consumer's guess.",
/// "enum": [
/// "cancel",
/// "suspend",
/// "resume"
/// ]
/// },
/// "reason": {
/// "description": "Human-readable explanation of why the operation was requested. Non-normative; intended for operator UI and audit records. A consumer MUST NOT condition its handling of the operation on this value.",
/// "type": "string",
/// "maxLength": 1024
/// },
/// "target": {
/// "description": "The specific Trust Task document this operation applies to. Per SPEC.md §12.2, `threadId`, `parentThreadId` and ceremony membership MUST NOT identify the target on their own: more than one document can occur in a single exchange or enactment.",
/// "type": "object",
/// "required": [
/// "id"
/// ],
/// "properties": {
/// "id": {
/// "description": "The `id` of the target Trust Task document. The sole identifying member.",
/// "type": "string",
/// "minLength": 1
/// },
/// "typeUri": {
/// "description": "The target document's `type`, including any `#request` fragment. RECOMMENDED. A consumer that holds the named `id` under a different specification can then detect the mismatch rather than acting on a coincidence of identifiers.",
/// "type": "string",
/// "format": "uri",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
///Vendor-namespaced extension data per SPEC.md §4.5.1. Every immediate child key MUST be a reverse-DNS prefix the producer controls.
#[serde(default, skip_serializing_if = "::serde_json::Map::is_empty")]
pub ext: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
/**
The control operation requested.
`cancel` stops the task permanently: it is terminal, and a cancelled task MUST NOT be resumed, retried, or cancelled again (SPEC.md §12.3). `suspend` halts further effects while preserving the consumer's current execution state — it does not undo work already performed. `resume` continues a suspended task from the state the consumer holds; a consumer MUST NOT resume after the target document's `expiresAt` (SPEC.md §12.5).
This is a discriminating field. A consumer that does not recognize a value MUST reject the document rather than apply a default — silently downgrading an unrecognized operation to a known one would let a producer's intent be replaced by the consumer's guess.*/
pub operation: PayloadOperation,
///Human-readable explanation of why the operation was requested. Non-normative; intended for operator UI and audit records. A consumer MUST NOT condition its handling of the operation on this value.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub reason: ::std::option::Option<PayloadReason>,
pub target: PayloadTarget,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
/**
The control operation requested.
`cancel` stops the task permanently: it is terminal, and a cancelled task MUST NOT be resumed, retried, or cancelled again (SPEC.md §12.3). `suspend` halts further effects while preserving the consumer's current execution state — it does not undo work already performed. `resume` continues a suspended task from the state the consumer holds; a consumer MUST NOT resume after the target document's `expiresAt` (SPEC.md §12.5).
This is a discriminating field. A consumer that does not recognize a value MUST reject the document rather than apply a default — silently downgrading an unrecognized operation to a known one would let a producer's intent be replaced by the consumer's guess.*/
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "\nThe control operation requested.\n\n`cancel` stops the task permanently: it is terminal, and a cancelled task MUST NOT be resumed, retried, or cancelled again (SPEC.md §12.3). `suspend` halts further effects while preserving the consumer's current execution state — it does not undo work already performed. `resume` continues a suspended task from the state the consumer holds; a consumer MUST NOT resume after the target document's `expiresAt` (SPEC.md §12.5).\n\nThis is a discriminating field. A consumer that does not recognize a value MUST reject the document rather than apply a default — silently downgrading an unrecognized operation to a known one would let a producer's intent be replaced by the consumer's guess.",
/// "enum": [
/// "cancel",
/// "suspend",
/// "resume"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum PayloadOperation {
#[serde(rename = "cancel")]
Cancel,
#[serde(rename = "suspend")]
Suspend,
#[serde(rename = "resume")]
Resume,
}
impl ::std::fmt::Display for PayloadOperation {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Cancel => f.write_str("cancel"),
Self::Suspend => f.write_str("suspend"),
Self::Resume => f.write_str("resume"),
}
}
}
impl ::std::str::FromStr for PayloadOperation {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"cancel" => Ok(Self::Cancel),
"suspend" => Ok(Self::Suspend),
"resume" => Ok(Self::Resume),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for PayloadOperation {
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 PayloadOperation {
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 PayloadOperation {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Human-readable explanation of why the operation was requested. Non-normative; intended for operator UI and audit records. A consumer MUST NOT condition its handling of the operation on this value.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Human-readable explanation of why the operation was requested. Non-normative; intended for operator UI and audit records. A consumer MUST NOT condition its handling of the operation on this value.",
/// "type": "string",
/// "maxLength": 1024
///}
/// ```
/// </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());
}
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 specific Trust Task document this operation applies to. Per SPEC.md §12.2, `threadId`, `parentThreadId` and ceremony membership MUST NOT identify the target on their own: more than one document can occur in a single exchange or enactment.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The specific Trust Task document this operation applies to. Per SPEC.md §12.2, `threadId`, `parentThreadId` and ceremony membership MUST NOT identify the target on their own: more than one document can occur in a single exchange or enactment.",
/// "type": "object",
/// "required": [
/// "id"
/// ],
/// "properties": {
/// "id": {
/// "description": "The `id` of the target Trust Task document. The sole identifying member.",
/// "type": "string",
/// "minLength": 1
/// },
/// "typeUri": {
/// "description": "The target document's `type`, including any `#request` fragment. RECOMMENDED. A consumer that holds the named `id` under a different specification can then detect the mismatch rather than acting on a coincidence of identifiers.",
/// "type": "string",
/// "format": "uri",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct PayloadTarget {
///The `id` of the target Trust Task document. The sole identifying member.
pub id: PayloadTargetId,
///The target document's `type`, including any `#request` fragment. RECOMMENDED. A consumer that holds the named `id` under a different specification can then detect the mismatch rather than acting on a coincidence of identifiers.
#[serde(
rename = "typeUri",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub type_uri: ::std::option::Option<::std::string::String>,
}
impl PayloadTarget {
pub fn builder() -> builder::PayloadTarget {
Default::default()
}
}
///The `id` of the target Trust Task document. The sole identifying member.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The `id` of the target Trust Task document. The sole identifying member.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PayloadTargetId(::std::string::String);
impl ::std::ops::Deref for PayloadTargetId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PayloadTargetId> for ::std::string::String {
fn from(value: PayloadTargetId) -> Self {
value.0
}
}
impl ::std::str::FromStr for PayloadTargetId {
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 PayloadTargetId {
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 PayloadTargetId {
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 PayloadTargetId {
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 PayloadTargetId {
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())
})
}
}
///What the consumer did. The `outcome` is the load-bearing member: it is what tells the producer whether a compensating action is required, since SPEC.md §12.4 declines to require rollback.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Response",
/// "description": "What the consumer did. The `outcome` is the load-bearing member: it is what tells the producer whether a compensating action is required, since SPEC.md §12.4 declines to require rollback.",
/// "type": "object",
/// "required": [
/// "operation",
/// "outcome",
/// "target"
/// ],
/// "properties": {
/// "effects": {
/// "description": "What was created, changed, disclosed, or exercised before the operation took hold. A consumer MUST populate this where `outcome` is `appliedWithEffects` or `alreadyCompleted` — a producer cannot decide whether to compensate without it — and the specification's Conformance section carries that requirement normatively. It is not expressed as a conditional schema because the registry's Rust code generator does not support if/then/else. The framework does not constrain how a task describes its own effects.",
/// "type": "array",
/// "items": {
/// "type": "object",
/// "required": [
/// "description"
/// ],
/// "properties": {
/// "description": {
/// "description": "Human-readable statement of the effect that occurred.",
/// "type": "string",
/// "maxLength": 1024,
/// "minLength": 1
/// },
/// "ref": {
/// "description": "An identifier for the effect where one exists — a credential id, a record identifier, a transaction reference — so a compensating task can name it.",
/// "type": "string"
/// },
/// "reversible": {
/// "description": "Whether the consumer believes this effect can be compensated by a further Trust Task. Advisory. Absent means unknown, which a producer SHOULD treat as no weaker than `false`.",
/// "type": "boolean"
/// }
/// },
/// "additionalProperties": false
/// }
/// },
/// "ext": {
/// "description": "Vendor-namespaced extension data per SPEC.md §4.5.1.",
/// "type": "object"
/// },
/// "operation": {
/// "description": "Echoed from the request, so the response is self-describing when retained apart from it.",
/// "enum": [
/// "cancel",
/// "suspend",
/// "resume"
/// ]
/// },
/// "outcome": {
/// "description": "\n`applied` — the operation took effect and NO irreversible or externally visible effect had occurred. The only outcome that means the task left no trace.\n\n`appliedWithEffects` — the operation took effect, but effects had already occurred before it did. `effects` describes them. A consumer MUST NOT report `applied` in this case (SPEC.md §12.3).\n\n`alreadyCompleted` — the task finished before the control document was processed. Not a cancellation; whether to compensate is the producer's own decision.\n\n`unknownTask` — the consumer holds no record of the target `id`, either because it never received it or because its acceptance window has lapsed. A consumer that records the operation as a tombstone against a not-yet-arrived document reports `applied`, not this.",
/// "enum": [
/// "applied",
/// "appliedWithEffects",
/// "alreadyCompleted",
/// "unknownTask"
/// ]
/// },
/// "target": {
/// "description": "Echoed from the request.",
/// "type": "object",
/// "required": [
/// "id"
/// ],
/// "properties": {
/// "id": {
/// "type": "string",
/// "minLength": 1
/// },
/// "typeUri": {
/// "type": "string",
/// "format": "uri",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "response"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Response {
///What was created, changed, disclosed, or exercised before the operation took hold. A consumer MUST populate this where `outcome` is `appliedWithEffects` or `alreadyCompleted` — a producer cannot decide whether to compensate without it — and the specification's Conformance section carries that requirement normatively. It is not expressed as a conditional schema because the registry's Rust code generator does not support if/then/else. The framework does not constrain how a task describes its own effects.
#[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
pub effects: ::std::vec::Vec<ResponseEffectsItem>,
///Vendor-namespaced extension data per SPEC.md §4.5.1.
#[serde(default, skip_serializing_if = "::serde_json::Map::is_empty")]
pub ext: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
///Echoed from the request, so the response is self-describing when retained apart from it.
pub operation: ResponseOperation,
/**
`applied` — the operation took effect and NO irreversible or externally visible effect had occurred. The only outcome that means the task left no trace.
`appliedWithEffects` — the operation took effect, but effects had already occurred before it did. `effects` describes them. A consumer MUST NOT report `applied` in this case (SPEC.md §12.3).
`alreadyCompleted` — the task finished before the control document was processed. Not a cancellation; whether to compensate is the producer's own decision.
`unknownTask` — the consumer holds no record of the target `id`, either because it never received it or because its acceptance window has lapsed. A consumer that records the operation as a tombstone against a not-yet-arrived document reports `applied`, not this.*/
pub outcome: ResponseOutcome,
pub target: ResponseTarget,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
///`ResponseEffectsItem`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "object",
/// "required": [
/// "description"
/// ],
/// "properties": {
/// "description": {
/// "description": "Human-readable statement of the effect that occurred.",
/// "type": "string",
/// "maxLength": 1024,
/// "minLength": 1
/// },
/// "ref": {
/// "description": "An identifier for the effect where one exists — a credential id, a record identifier, a transaction reference — so a compensating task can name it.",
/// "type": "string"
/// },
/// "reversible": {
/// "description": "Whether the consumer believes this effect can be compensated by a further Trust Task. Advisory. Absent means unknown, which a producer SHOULD treat as no weaker than `false`.",
/// "type": "boolean"
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct ResponseEffectsItem {
///Human-readable statement of the effect that occurred.
pub description: ResponseEffectsItemDescription,
///An identifier for the effect where one exists — a credential id, a record identifier, a transaction reference — so a compensating task can name it.
#[serde(
rename = "ref",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub ref_: ::std::option::Option<::std::string::String>,
///Whether the consumer believes this effect can be compensated by a further Trust Task. Advisory. Absent means unknown, which a producer SHOULD treat as no weaker than `false`.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub reversible: ::std::option::Option<bool>,
}
impl ResponseEffectsItem {
pub fn builder() -> builder::ResponseEffectsItem {
Default::default()
}
}
///Human-readable statement of the effect that occurred.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Human-readable statement of the effect that occurred.",
/// "type": "string",
/// "maxLength": 1024,
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ResponseEffectsItemDescription(::std::string::String);
impl ::std::ops::Deref for ResponseEffectsItemDescription {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ResponseEffectsItemDescription> for ::std::string::String {
fn from(value: ResponseEffectsItemDescription) -> Self {
value.0
}
}
impl ::std::str::FromStr for ResponseEffectsItemDescription {
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 ResponseEffectsItemDescription {
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 ResponseEffectsItemDescription {
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 ResponseEffectsItemDescription {
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 ResponseEffectsItemDescription {
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())
})
}
}
///Echoed from the request, so the response is self-describing when retained apart from it.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Echoed from the request, so the response is self-describing when retained apart from it.",
/// "enum": [
/// "cancel",
/// "suspend",
/// "resume"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ResponseOperation {
#[serde(rename = "cancel")]
Cancel,
#[serde(rename = "suspend")]
Suspend,
#[serde(rename = "resume")]
Resume,
}
impl ::std::fmt::Display for ResponseOperation {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Cancel => f.write_str("cancel"),
Self::Suspend => f.write_str("suspend"),
Self::Resume => f.write_str("resume"),
}
}
}
impl ::std::str::FromStr for ResponseOperation {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"cancel" => Ok(Self::Cancel),
"suspend" => Ok(Self::Suspend),
"resume" => Ok(Self::Resume),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ResponseOperation {
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 ResponseOperation {
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 ResponseOperation {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
/**
`applied` — the operation took effect and NO irreversible or externally visible effect had occurred. The only outcome that means the task left no trace.
`appliedWithEffects` — the operation took effect, but effects had already occurred before it did. `effects` describes them. A consumer MUST NOT report `applied` in this case (SPEC.md §12.3).
`alreadyCompleted` — the task finished before the control document was processed. Not a cancellation; whether to compensate is the producer's own decision.
`unknownTask` — the consumer holds no record of the target `id`, either because it never received it or because its acceptance window has lapsed. A consumer that records the operation as a tombstone against a not-yet-arrived document reports `applied`, not this.*/
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "\n`applied` — the operation took effect and NO irreversible or externally visible effect had occurred. The only outcome that means the task left no trace.\n\n`appliedWithEffects` — the operation took effect, but effects had already occurred before it did. `effects` describes them. A consumer MUST NOT report `applied` in this case (SPEC.md §12.3).\n\n`alreadyCompleted` — the task finished before the control document was processed. Not a cancellation; whether to compensate is the producer's own decision.\n\n`unknownTask` — the consumer holds no record of the target `id`, either because it never received it or because its acceptance window has lapsed. A consumer that records the operation as a tombstone against a not-yet-arrived document reports `applied`, not this.",
/// "enum": [
/// "applied",
/// "appliedWithEffects",
/// "alreadyCompleted",
/// "unknownTask"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ResponseOutcome {
#[serde(rename = "applied")]
Applied,
#[serde(rename = "appliedWithEffects")]
AppliedWithEffects,
#[serde(rename = "alreadyCompleted")]
AlreadyCompleted,
#[serde(rename = "unknownTask")]
UnknownTask,
}
impl ::std::fmt::Display for ResponseOutcome {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Applied => f.write_str("applied"),
Self::AppliedWithEffects => f.write_str("appliedWithEffects"),
Self::AlreadyCompleted => f.write_str("alreadyCompleted"),
Self::UnknownTask => f.write_str("unknownTask"),
}
}
}
impl ::std::str::FromStr for ResponseOutcome {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"applied" => Ok(Self::Applied),
"appliedWithEffects" => Ok(Self::AppliedWithEffects),
"alreadyCompleted" => Ok(Self::AlreadyCompleted),
"unknownTask" => Ok(Self::UnknownTask),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ResponseOutcome {
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 ResponseOutcome {
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 ResponseOutcome {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Echoed from the request.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Echoed from the request.",
/// "type": "object",
/// "required": [
/// "id"
/// ],
/// "properties": {
/// "id": {
/// "type": "string",
/// "minLength": 1
/// },
/// "typeUri": {
/// "type": "string",
/// "format": "uri",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct ResponseTarget {
pub id: ResponseTargetId,
#[serde(
rename = "typeUri",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub type_uri: ::std::option::Option<::std::string::String>,
}
impl ResponseTarget {
pub fn builder() -> builder::ResponseTarget {
Default::default()
}
}
///`ResponseTargetId`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ResponseTargetId(::std::string::String);
impl ::std::ops::Deref for ResponseTargetId {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ResponseTargetId> for ::std::string::String {
fn from(value: ResponseTargetId) -> Self {
value.0
}
}
impl ::std::str::FromStr for ResponseTargetId {
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 ResponseTargetId {
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 ResponseTargetId {
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 ResponseTargetId {
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 ResponseTargetId {
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 Payload {
ext: ::std::result::Result<
::serde_json::Map<::std::string::String, ::serde_json::Value>,
::std::string::String,
>,
operation: ::std::result::Result<super::PayloadOperation, ::std::string::String>,
reason: ::std::result::Result<
::std::option::Option<super::PayloadReason>,
::std::string::String,
>,
target: ::std::result::Result<super::PayloadTarget, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
ext: Ok(Default::default()),
operation: Err("no value supplied for operation".to_string()),
reason: Ok(Default::default()),
target: Err("no value supplied for target".to_string()),
}
}
}
impl Payload {
pub fn ext<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.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn operation<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PayloadOperation>,
T::Error: ::std::fmt::Display,
{
self.operation = value
.try_into()
.map_err(|e| format!("error converting supplied value for operation: {e}"));
self
}
pub fn reason<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<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 target<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PayloadTarget>,
T::Error: ::std::fmt::Display,
{
self.target = value
.try_into()
.map_err(|e| format!("error converting supplied value for target: {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?,
operation: value.operation?,
reason: value.reason?,
target: value.target?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
ext: Ok(value.ext),
operation: Ok(value.operation),
reason: Ok(value.reason),
target: Ok(value.target),
}
}
}
#[derive(Clone, Debug)]
pub struct PayloadTarget {
id: ::std::result::Result<super::PayloadTargetId, ::std::string::String>,
type_uri: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
}
impl ::std::default::Default for PayloadTarget {
fn default() -> Self {
Self {
id: Err("no value supplied for id".to_string()),
type_uri: Ok(Default::default()),
}
}
}
impl PayloadTarget {
pub fn id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PayloadTargetId>,
T::Error: ::std::fmt::Display,
{
self.id = value
.try_into()
.map_err(|e| format!("error converting supplied value for id: {e}"));
self
}
pub fn type_uri<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.type_uri = value
.try_into()
.map_err(|e| format!("error converting supplied value for type_uri: {e}"));
self
}
}
impl ::std::convert::TryFrom<PayloadTarget> for super::PayloadTarget {
type Error = super::error::ConversionError;
fn try_from(
value: PayloadTarget,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
id: value.id?,
type_uri: value.type_uri?,
})
}
}
impl ::std::convert::From<super::PayloadTarget> for PayloadTarget {
fn from(value: super::PayloadTarget) -> Self {
Self {
id: Ok(value.id),
type_uri: Ok(value.type_uri),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
effects: ::std::result::Result<
::std::vec::Vec<super::ResponseEffectsItem>,
::std::string::String,
>,
ext: ::std::result::Result<
::serde_json::Map<::std::string::String, ::serde_json::Value>,
::std::string::String,
>,
operation: ::std::result::Result<super::ResponseOperation, ::std::string::String>,
outcome: ::std::result::Result<super::ResponseOutcome, ::std::string::String>,
target: ::std::result::Result<super::ResponseTarget, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
effects: Ok(Default::default()),
ext: Ok(Default::default()),
operation: Err("no value supplied for operation".to_string()),
outcome: Err("no value supplied for outcome".to_string()),
target: Err("no value supplied for target".to_string()),
}
}
}
impl Response {
pub fn effects<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::vec::Vec<super::ResponseEffectsItem>>,
T::Error: ::std::fmt::Display,
{
self.effects = value
.try_into()
.map_err(|e| format!("error converting supplied value for effects: {e}"));
self
}
pub fn ext<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.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn operation<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseOperation>,
T::Error: ::std::fmt::Display,
{
self.operation = value
.try_into()
.map_err(|e| format!("error converting supplied value for operation: {e}"));
self
}
pub fn outcome<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseOutcome>,
T::Error: ::std::fmt::Display,
{
self.outcome = value
.try_into()
.map_err(|e| format!("error converting supplied value for outcome: {e}"));
self
}
pub fn target<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseTarget>,
T::Error: ::std::fmt::Display,
{
self.target = value
.try_into()
.map_err(|e| format!("error converting supplied value for target: {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 {
effects: value.effects?,
ext: value.ext?,
operation: value.operation?,
outcome: value.outcome?,
target: value.target?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
effects: Ok(value.effects),
ext: Ok(value.ext),
operation: Ok(value.operation),
outcome: Ok(value.outcome),
target: Ok(value.target),
}
}
}
#[derive(Clone, Debug)]
pub struct ResponseEffectsItem {
description:
::std::result::Result<super::ResponseEffectsItemDescription, ::std::string::String>,
ref_: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
reversible: ::std::result::Result<::std::option::Option<bool>, ::std::string::String>,
}
impl ::std::default::Default for ResponseEffectsItem {
fn default() -> Self {
Self {
description: Err("no value supplied for description".to_string()),
ref_: Ok(Default::default()),
reversible: Ok(Default::default()),
}
}
}
impl ResponseEffectsItem {
pub fn description<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseEffectsItemDescription>,
T::Error: ::std::fmt::Display,
{
self.description = value
.try_into()
.map_err(|e| format!("error converting supplied value for description: {e}"));
self
}
pub fn ref_<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.ref_ = value
.try_into()
.map_err(|e| format!("error converting supplied value for ref_: {e}"));
self
}
pub fn reversible<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<bool>>,
T::Error: ::std::fmt::Display,
{
self.reversible = value
.try_into()
.map_err(|e| format!("error converting supplied value for reversible: {e}"));
self
}
}
impl ::std::convert::TryFrom<ResponseEffectsItem> for super::ResponseEffectsItem {
type Error = super::error::ConversionError;
fn try_from(
value: ResponseEffectsItem,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
description: value.description?,
ref_: value.ref_?,
reversible: value.reversible?,
})
}
}
impl ::std::convert::From<super::ResponseEffectsItem> for ResponseEffectsItem {
fn from(value: super::ResponseEffectsItem) -> Self {
Self {
description: Ok(value.description),
ref_: Ok(value.ref_),
reversible: Ok(value.reversible),
}
}
}
#[derive(Clone, Debug)]
pub struct ResponseTarget {
id: ::std::result::Result<super::ResponseTargetId, ::std::string::String>,
type_uri: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
}
impl ::std::default::Default for ResponseTarget {
fn default() -> Self {
Self {
id: Err("no value supplied for id".to_string()),
type_uri: Ok(Default::default()),
}
}
}
impl ResponseTarget {
pub fn id<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseTargetId>,
T::Error: ::std::fmt::Display,
{
self.id = value
.try_into()
.map_err(|e| format!("error converting supplied value for id: {e}"));
self
}
pub fn type_uri<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.type_uri = value
.try_into()
.map_err(|e| format!("error converting supplied value for type_uri: {e}"));
self
}
}
impl ::std::convert::TryFrom<ResponseTarget> for super::ResponseTarget {
type Error = super::error::ConversionError;
fn try_from(
value: ResponseTarget,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
id: value.id?,
type_uri: value.type_uri?,
})
}
}
impl ::std::convert::From<super::ResponseTarget> for ResponseTarget {
fn from(value: super::ResponseTarget) -> Self {
Self {
id: Ok(value.id),
type_uri: Ok(value.type_uri),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/trust-task-control/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 \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"What the consumer did. The `outcome` is the load-bearing member: it is what tells the producer whether a compensating action is required, since SPEC.md §12.4 declines to require rollback.\",\n \"properties\": {\n \"effects\": {\n \"description\": \"What was created, changed, disclosed, or exercised before the operation took hold. A consumer MUST populate this where `outcome` is `appliedWithEffects` or `alreadyCompleted` — a producer cannot decide whether to compensate without it — and the specification's Conformance section carries that requirement normatively. It is not expressed as a conditional schema because the registry's Rust code generator does not support if/then/else. The framework does not constrain how a task describes its own effects.\",\n \"items\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"description\": {\n \"description\": \"Human-readable statement of the effect that occurred.\",\n \"maxLength\": 1024,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"ref\": {\n \"description\": \"An identifier for the effect where one exists — a credential id, a record identifier, a transaction reference — so a compensating task can name it.\",\n \"type\": \"string\"\n },\n \"reversible\": {\n \"description\": \"Whether the consumer believes this effect can be compensated by a further Trust Task. Advisory. Absent means unknown, which a producer SHOULD treat as no weaker than `false`.\",\n \"type\": \"boolean\"\n }\n },\n \"required\": [\n \"description\"\n ],\n \"type\": \"object\"\n },\n \"type\": \"array\"\n },\n \"ext\": {\n \"description\": \"Vendor-namespaced extension data per SPEC.md §4.5.1.\",\n \"type\": \"object\"\n },\n \"operation\": {\n \"description\": \"Echoed from the request, so the response is self-describing when retained apart from it.\",\n \"enum\": [\n \"cancel\",\n \"suspend\",\n \"resume\"\n ]\n },\n \"outcome\": {\n \"description\": \"`applied` — the operation took effect and NO irreversible or externally visible effect had occurred. The only outcome that means the task left no trace.\\n\\n`appliedWithEffects` — the operation took effect, but effects had already occurred before it did. `effects` describes them. A consumer MUST NOT report `applied` in this case (SPEC.md §12.3).\\n\\n`alreadyCompleted` — the task finished before the control document was processed. Not a cancellation; whether to compensate is the producer's own decision.\\n\\n`unknownTask` — the consumer holds no record of the target `id`, either because it never received it or because its acceptance window has lapsed. A consumer that records the operation as a tombstone against a not-yet-arrived document reports `applied`, not this.\",\n \"enum\": [\n \"applied\",\n \"appliedWithEffects\",\n \"alreadyCompleted\",\n \"unknownTask\"\n ]\n },\n \"target\": {\n \"additionalProperties\": false,\n \"description\": \"Echoed from the request.\",\n \"properties\": {\n \"id\": {\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"typeUri\": {\n \"format\": \"uri\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"id\"\n ],\n \"type\": \"object\"\n }\n },\n \"required\": [\n \"operation\",\n \"target\",\n \"outcome\"\n ],\n \"title\": \"Trust Task Control — response payload\",\n \"type\": \"object\"\n }\n },\n \"$id\": \"https://trusttasks.org/spec/trust-task-control/0.1\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"additionalProperties\": false,\n \"description\": \"The task-control request defined at SPEC.md §12: a producer withdrawing, pausing, or resuming work a consumer has already accepted.\\n\\nThis is a REQUEST, not a response. A consumer that stops work on its own initiative does not send one of these — it returns a trust-task-error carrying `cancelled`, so that a withdrawal and a refusal remain distinguishable to every party and to any auditor reading the retained documents afterwards.\\n\\nThe operation takes effect through SPEC.md §7.2 item 12: a valid, authorized control operation is one of the conditions a consumer re-evaluates immediately before each irreversible or externally visible effect. There is no separate race protocol.\",\n \"properties\": {\n \"ext\": {\n \"description\": \"Vendor-namespaced extension data per SPEC.md §4.5.1. Every immediate child key MUST be a reverse-DNS prefix the producer controls.\",\n \"type\": \"object\"\n },\n \"operation\": {\n \"description\": \"The control operation requested.\\n\\n`cancel` stops the task permanently: it is terminal, and a cancelled task MUST NOT be resumed, retried, or cancelled again (SPEC.md §12.3). `suspend` halts further effects while preserving the consumer's current execution state — it does not undo work already performed. `resume` continues a suspended task from the state the consumer holds; a consumer MUST NOT resume after the target document's `expiresAt` (SPEC.md §12.5).\\n\\nThis is a discriminating field. A consumer that does not recognize a value MUST reject the document rather than apply a default — silently downgrading an unrecognized operation to a known one would let a producer's intent be replaced by the consumer's guess.\",\n \"enum\": [\n \"cancel\",\n \"suspend\",\n \"resume\"\n ]\n },\n \"reason\": {\n \"description\": \"Human-readable explanation of why the operation was requested. Non-normative; intended for operator UI and audit records. A consumer MUST NOT condition its handling of the operation on this value.\",\n \"maxLength\": 1024,\n \"type\": \"string\"\n },\n \"target\": {\n \"additionalProperties\": false,\n \"description\": \"The specific Trust Task document this operation applies to. Per SPEC.md §12.2, `threadId`, `parentThreadId` and ceremony membership MUST NOT identify the target on their own: more than one document can occur in a single exchange or enactment.\",\n \"properties\": {\n \"id\": {\n \"description\": \"The `id` of the target Trust Task document. The sole identifying member.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"typeUri\": {\n \"description\": \"The target document's `type`, including any `#request` fragment. RECOMMENDED. A consumer that holds the named `id` under a different specification can then detect the mismatch rather than acting on a coincidence of identifiers.\",\n \"format\": \"uri\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"id\"\n ],\n \"type\": \"object\"\n }\n },\n \"required\": [\n \"operation\",\n \"target\"\n ],\n \"title\": \"Trust Task Control — payload\",\n \"type\": \"object\"\n}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/trust-task-control/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 \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"description\": \"What the consumer did. The `outcome` is the load-bearing member: it is what tells the producer whether a compensating action is required, since SPEC.md §12.4 declines to require rollback.\",\n \"properties\": {\n \"effects\": {\n \"description\": \"What was created, changed, disclosed, or exercised before the operation took hold. A consumer MUST populate this where `outcome` is `appliedWithEffects` or `alreadyCompleted` — a producer cannot decide whether to compensate without it — and the specification's Conformance section carries that requirement normatively. It is not expressed as a conditional schema because the registry's Rust code generator does not support if/then/else. The framework does not constrain how a task describes its own effects.\",\n \"items\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"description\": {\n \"description\": \"Human-readable statement of the effect that occurred.\",\n \"maxLength\": 1024,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"ref\": {\n \"description\": \"An identifier for the effect where one exists — a credential id, a record identifier, a transaction reference — so a compensating task can name it.\",\n \"type\": \"string\"\n },\n \"reversible\": {\n \"description\": \"Whether the consumer believes this effect can be compensated by a further Trust Task. Advisory. Absent means unknown, which a producer SHOULD treat as no weaker than `false`.\",\n \"type\": \"boolean\"\n }\n },\n \"required\": [\n \"description\"\n ],\n \"type\": \"object\"\n },\n \"type\": \"array\"\n },\n \"ext\": {\n \"description\": \"Vendor-namespaced extension data per SPEC.md §4.5.1.\",\n \"type\": \"object\"\n },\n \"operation\": {\n \"description\": \"Echoed from the request, so the response is self-describing when retained apart from it.\",\n \"enum\": [\n \"cancel\",\n \"suspend\",\n \"resume\"\n ]\n },\n \"outcome\": {\n \"description\": \"`applied` — the operation took effect and NO irreversible or externally visible effect had occurred. The only outcome that means the task left no trace.\\n\\n`appliedWithEffects` — the operation took effect, but effects had already occurred before it did. `effects` describes them. A consumer MUST NOT report `applied` in this case (SPEC.md §12.3).\\n\\n`alreadyCompleted` — the task finished before the control document was processed. Not a cancellation; whether to compensate is the producer's own decision.\\n\\n`unknownTask` — the consumer holds no record of the target `id`, either because it never received it or because its acceptance window has lapsed. A consumer that records the operation as a tombstone against a not-yet-arrived document reports `applied`, not this.\",\n \"enum\": [\n \"applied\",\n \"appliedWithEffects\",\n \"alreadyCompleted\",\n \"unknownTask\"\n ]\n },\n \"target\": {\n \"additionalProperties\": false,\n \"description\": \"Echoed from the request.\",\n \"properties\": {\n \"id\": {\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"typeUri\": {\n \"format\": \"uri\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"id\"\n ],\n \"type\": \"object\"\n }\n },\n \"required\": [\n \"operation\",\n \"target\",\n \"outcome\"\n ],\n \"title\": \"Trust Task Control — 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;
}