//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `process-attestation`. Version: `0.1`.
/// Why this specification version is deprecated (SPEC "Superseded and
/// Withdrawn Versions"), or `None` while it is current.
pub const DEPRECATION: Option<&str> = None;
#[allow(unused_imports)]
use serde::{Deserialize, Serialize};
/// Error types.
pub mod error {
/// Error from a `TryFrom` or `FromStr` implementation.
pub struct ConversionError(::std::borrow::Cow<'static, str>);
impl ::std::error::Error for ConversionError {}
impl ::std::fmt::Display for ConversionError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> {
::std::fmt::Display::fmt(&self.0, f)
}
}
impl ::std::fmt::Debug for ConversionError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> {
::std::fmt::Debug::fmt(&self.0, f)
}
}
impl From<&'static str> for ConversionError {
fn from(value: &'static str) -> Self {
Self(value.into())
}
}
impl From<String> for ConversionError {
fn from(value: String) -> Self {
Self(value.into())
}
}
}
///Deterministic identification of the object whose production is in question.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Artifact {
///Carried verbatim from the IANA Named Information Hash Algorithm registry, not re-cased — SPEC §4.10 externally-owned values.
pub algorithm: ArtifactAlgorithm,
#[serde(
rename = "byteLength",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub byte_length: ::std::option::Option<u64>,
///base64url, unpadded.
pub digest: ArtifactDigest,
}
impl Artifact {
pub fn builder() -> builder::Artifact {
Default::default()
}
}
///Carried verbatim from the IANA Named Information Hash Algorithm registry, not re-cased — SPEC §4.10 externally-owned values.
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ArtifactAlgorithm {
#[serde(rename = "sha-256")]
Sha256,
#[serde(rename = "sha-384")]
Sha384,
#[serde(rename = "sha-512")]
Sha512,
#[serde(rename = "blake3")]
Blake3,
}
impl ::std::fmt::Display for ArtifactAlgorithm {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Sha256 => f.write_str("sha-256"),
Self::Sha384 => f.write_str("sha-384"),
Self::Sha512 => f.write_str("sha-512"),
Self::Blake3 => f.write_str("blake3"),
}
}
}
impl ::std::str::FromStr for ArtifactAlgorithm {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"sha-256" => Ok(Self::Sha256),
"sha-384" => Ok(Self::Sha384),
"sha-512" => Ok(Self::Sha512),
"blake3" => Ok(Self::Blake3),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ArtifactAlgorithm {
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 ArtifactAlgorithm {
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 ArtifactAlgorithm {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///base64url, unpadded.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ArtifactDigest(::std::string::String);
impl ::std::ops::Deref for ArtifactDigest {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ArtifactDigest> for ::std::string::String {
fn from(value: ArtifactDigest) -> Self {
value.0
}
}
impl ::std::str::FromStr for ArtifactDigest {
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-Za-z0-9_-]{43,128}$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[A-Za-z0-9_-]{43,128}$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ArtifactDigest {
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 ArtifactDigest {
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 ArtifactDigest {
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 ArtifactDigest {
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 at the task layer. The task standardizes the interaction, not the receipt.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Assessment {
///The primitive's confidence in `determination`, as an integer percentage. An integer rather than a fraction because no other specification in this registry puts a floating-point value on the wire: a float's textual form is not stable across JSON implementations, which makes byte-exact re-serialization a language-dependent property.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub confidence: ::std::option::Option<i64>,
///Primitive-defined. Deliberately not normalized across primitives: a determination means only what the primitive that produced it defines it to mean.
pub determination: AssessmentDetermination,
///Specification the receipt is verified under. Names which vocabulary `determination` belongs to.
pub primitive: ::std::string::String,
}
impl Assessment {
pub fn builder() -> builder::Assessment {
Default::default()
}
}
///Primitive-defined. Deliberately not normalized across primitives: a determination means only what the primitive that produced it defines it to mean.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct AssessmentDetermination(::std::string::String);
impl ::std::ops::Deref for AssessmentDetermination {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<AssessmentDetermination> for ::std::string::String {
fn from(value: AssessmentDetermination) -> Self {
value.0
}
}
impl ::std::str::FromStr for AssessmentDetermination {
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 AssessmentDetermination {
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 AssessmentDetermination {
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 AssessmentDetermination {
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 AssessmentDetermination {
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())
})
}
}
///Only the categories the request asked for.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Disclosed {
#[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
pub anchors: ::std::vec::Vec<DisclosedAnchorsItem>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub document: ::std::option::Option<DisclosedDocument>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub integrity: ::std::option::Option<DisclosedIntegrity>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub timeline: ::std::option::Option<DisclosedTimeline>,
}
impl ::std::default::Default for Disclosed {
fn default() -> Self {
Self {
anchors: Default::default(),
document: Default::default(),
integrity: Default::default(),
timeline: Default::default(),
}
}
}
impl Disclosed {
pub fn builder() -> builder::Disclosed {
Default::default()
}
}
///`DisclosedAnchorsItem`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct DisclosedAnchorsItem {
#[serde(
rename = "anchoredAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub anchored_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
pub kind: DisclosedAnchorsItemKind,
}
impl DisclosedAnchorsItem {
pub fn builder() -> builder::DisclosedAnchorsItem {
Default::default()
}
}
///`DisclosedAnchorsItemKind`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum DisclosedAnchorsItemKind {
#[serde(rename = "rfc3161")]
Rfc3161,
#[serde(rename = "opentimestamps")]
Opentimestamps,
#[serde(rename = "roughtime")]
Roughtime,
}
impl ::std::fmt::Display for DisclosedAnchorsItemKind {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Rfc3161 => f.write_str("rfc3161"),
Self::Opentimestamps => f.write_str("opentimestamps"),
Self::Roughtime => f.write_str("roughtime"),
}
}
}
impl ::std::str::FromStr for DisclosedAnchorsItemKind {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"rfc3161" => Ok(Self::Rfc3161),
"opentimestamps" => Ok(Self::Opentimestamps),
"roughtime" => Ok(Self::Roughtime),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for DisclosedAnchorsItemKind {
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 DisclosedAnchorsItemKind {
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 DisclosedAnchorsItemKind {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///`DisclosedDocument`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct DisclosedDocument {
#[serde(
rename = "mediaType",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub media_type: ::std::option::Option<DisclosedDocumentMediaType>,
}
impl ::std::default::Default for DisclosedDocument {
fn default() -> Self {
Self {
media_type: Default::default(),
}
}
}
impl DisclosedDocument {
pub fn builder() -> builder::DisclosedDocument {
Default::default()
}
}
///`DisclosedDocumentMediaType`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct DisclosedDocumentMediaType(::std::string::String);
impl ::std::ops::Deref for DisclosedDocumentMediaType {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<DisclosedDocumentMediaType> for ::std::string::String {
fn from(value: DisclosedDocumentMediaType) -> Self {
value.0
}
}
impl ::std::str::FromStr for DisclosedDocumentMediaType {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 255usize {
return Err("longer than 255 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for DisclosedDocumentMediaType {
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 DisclosedDocumentMediaType {
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 DisclosedDocumentMediaType {
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 DisclosedDocumentMediaType {
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())
})
}
}
///`DisclosedIntegrity`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct DisclosedIntegrity {
#[serde(
rename = "chainValid",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub chain_valid: ::std::option::Option<bool>,
#[serde(
rename = "keyCustody",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub key_custody: ::std::option::Option<DisclosedIntegrityKeyCustody>,
#[serde(
rename = "signatureValid",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub signature_valid: ::std::option::Option<bool>,
}
impl ::std::default::Default for DisclosedIntegrity {
fn default() -> Self {
Self {
chain_valid: Default::default(),
key_custody: Default::default(),
signature_valid: Default::default(),
}
}
}
impl DisclosedIntegrity {
pub fn builder() -> builder::DisclosedIntegrity {
Default::default()
}
}
///`DisclosedIntegrityKeyCustody`
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum DisclosedIntegrityKeyCustody {
#[serde(rename = "software")]
Software,
#[serde(rename = "tpm")]
Tpm,
#[serde(rename = "secureEnclave")]
SecureEnclave,
}
impl ::std::fmt::Display for DisclosedIntegrityKeyCustody {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Software => f.write_str("software"),
Self::Tpm => f.write_str("tpm"),
Self::SecureEnclave => f.write_str("secureEnclave"),
}
}
}
impl ::std::str::FromStr for DisclosedIntegrityKeyCustody {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"software" => Ok(Self::Software),
"tpm" => Ok(Self::Tpm),
"secureEnclave" => Ok(Self::SecureEnclave),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for DisclosedIntegrityKeyCustody {
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 DisclosedIntegrityKeyCustody {
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 DisclosedIntegrityKeyCustody {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///`DisclosedTimeline`
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct DisclosedTimeline {
#[serde(
rename = "checkpointCount",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub checkpoint_count: ::std::option::Option<u64>,
#[serde(
rename = "endedAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub ended_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
#[serde(
rename = "startedAt",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub started_at: ::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
}
impl ::std::default::Default for DisclosedTimeline {
fn default() -> Self {
Self {
checkpoint_count: Default::default(),
ended_at: Default::default(),
started_at: Default::default(),
}
}
}
impl DisclosedTimeline {
pub fn builder() -> builder::DisclosedTimeline {
Default::default()
}
}
///Derived aggregates only. An enum rather than a pattern so a primitive cannot widen its own disclosure surface by inventing a name. The determination itself is not a category: it is always in `assessment` when the result is `attested`. Raw behavioral samples and fingerprints are out of scope for 0.1.
///
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum DisclosureCategory {
#[serde(rename = "document")]
Document,
#[serde(rename = "timeline")]
Timeline,
#[serde(rename = "integrity")]
Integrity,
#[serde(rename = "anchors")]
Anchors,
}
impl ::std::fmt::Display for DisclosureCategory {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Document => f.write_str("document"),
Self::Timeline => f.write_str("timeline"),
Self::Integrity => f.write_str("integrity"),
Self::Anchors => f.write_str("anchors"),
}
}
}
impl ::std::str::FromStr for DisclosureCategory {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"document" => Ok(Self::Document),
"timeline" => Ok(Self::Timeline),
"integrity" => Ok(Self::Integrity),
"anchors" => Ok(Self::Anchors),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for DisclosureCategory {
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 DisclosureCategory {
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 DisclosureCategory {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
///Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct Ext(pub ::std::collections::HashMap<ExtKey, ::serde_json::Value>);
impl ::std::ops::Deref for Ext {
type Target = ::std::collections::HashMap<ExtKey, ::serde_json::Value>;
fn deref(&self) -> &::std::collections::HashMap<ExtKey, ::serde_json::Value> {
&self.0
}
}
impl ::std::convert::From<Ext> for ::std::collections::HashMap<ExtKey, ::serde_json::Value> {
fn from(value: Ext) -> Self {
value.0
}
}
impl ::std::convert::From<::std::collections::HashMap<ExtKey, ::serde_json::Value>> for Ext {
fn from(value: ::std::collections::HashMap<ExtKey, ::serde_json::Value>) -> Self {
Self(value)
}
}
///`ExtKey`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ExtKey(::std::string::String);
impl ::std::ops::Deref for ExtKey {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ExtKey> for ::std::string::String {
fn from(value: ExtKey) -> Self {
value.0
}
}
impl ::std::str::FromStr for ExtKey {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for ExtKey {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///What a Verifier asks of a Holder: identify an artifact by digest, supply a freshness challenge, and name the disclosure categories wanted. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, proof) are owned by the framework — SPEC §6.3.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
pub artifact: Artifact,
///Verifier-supplied freshness nonce, echoed verbatim in the response. The floor is 16 characters because anti-replay is the only integrity property the request has.
pub challenge: PayloadChallenge,
///Categories the Verifier requests. A Holder MAY return fewer; it MUST NOT return more.
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub disclosure: ::std::option::Option<Vec<DisclosureCategory>>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///Verifier-supplied freshness nonce, echoed verbatim in the response. The floor is 16 characters because anti-replay is the only integrity property the request has.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PayloadChallenge(::std::string::String);
impl ::std::ops::Deref for PayloadChallenge {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PayloadChallenge> for ::std::string::String {
fn from(value: PayloadChallenge) -> Self {
value.0
}
}
impl ::std::str::FromStr for PayloadChallenge {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 256usize {
return Err("longer than 256 characters".into());
}
if value.chars().count() < 16usize {
return Err("shorter than 16 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for PayloadChallenge {
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 PayloadChallenge {
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 PayloadChallenge {
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 PayloadChallenge {
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())
})
}
}
///Tagged union. Inline exists for Verifiers that cannot dereference a URI at verification time.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(tag = "type", deny_unknown_fields)]
#[non_exhaustive]
pub enum ReceiptReference {
#[serde(rename = "uri")]
Uri {
#[serde(
rename = "mediaType",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
media_type: ::std::option::Option<ReceiptReferenceMediaType>,
uri: ::std::string::String,
},
#[serde(rename = "inline")]
Inline {
///base64url, unpadded. Bounded at 256 KiB of encoded text (~192 KiB of receipt): inline exists for the offline case, not as the general transport. A receipt larger than the bound MUST use the `uri` form.
data: ReceiptReferenceData,
#[serde(rename = "mediaType")]
media_type: ReceiptReferenceMediaType,
},
}
///base64url, unpadded. Bounded at 256 KiB of encoded text (~192 KiB of receipt): inline exists for the offline case, not as the general transport. A receipt larger than the bound MUST use the `uri` form.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ReceiptReferenceData(::std::string::String);
impl ::std::ops::Deref for ReceiptReferenceData {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ReceiptReferenceData> for ::std::string::String {
fn from(value: ReceiptReferenceData) -> Self {
value.0
}
}
impl ::std::str::FromStr for ReceiptReferenceData {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 262144usize {
return Err("longer than 262144 characters".into());
}
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| ::regress::Regex::new("^[A-Za-z0-9_-]+$").unwrap());
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[A-Za-z0-9_-]+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ReceiptReferenceData {
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 ReceiptReferenceData {
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 ReceiptReferenceData {
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 ReceiptReferenceData {
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())
})
}
}
///`ReceiptReferenceMediaType`
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ReceiptReferenceMediaType(::std::string::String);
impl ::std::ops::Deref for ReceiptReferenceMediaType {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ReceiptReferenceMediaType> for ::std::string::String {
fn from(value: ReceiptReferenceMediaType) -> Self {
value.0
}
}
impl ::std::str::FromStr for ReceiptReferenceMediaType {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 255usize {
return Err("longer than 255 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ReceiptReferenceMediaType {
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 ReceiptReferenceMediaType {
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 ReceiptReferenceMediaType {
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 ReceiptReferenceMediaType {
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 Holder's answer. Failures use trust-task-error, not this shape. Both results share one response type so the envelope carries no observable distinction between them. `result` is the discriminator and stays inside the payload, so one envelope type covers both branches.
///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(tag = "result", deny_unknown_fields)]
#[non_exhaustive]
pub enum Response {
///Attested
#[serde(rename = "attested")]
Attested {
artifact: Artifact,
assessment: Assessment,
///The request's challenge, echoed verbatim.
challenge: ResponseChallenge,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
disclosed: ::std::option::Option<Disclosed>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
ext: ::std::option::Option<Ext>,
#[serde(rename = "receiptReference")]
receipt_reference: ReceiptReference,
},
///Unavailable
#[serde(rename = "unavailable")]
Unavailable {
artifact: Artifact,
///The request's challenge, echoed verbatim.
challenge: ResponseChallenge,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
ext: ::std::option::Option<Ext>,
},
}
///The request's challenge, echoed verbatim.
///
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ResponseChallenge(::std::string::String);
impl ::std::ops::Deref for ResponseChallenge {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ResponseChallenge> for ::std::string::String {
fn from(value: ResponseChallenge) -> Self {
value.0
}
}
impl ::std::str::FromStr for ResponseChallenge {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() > 256usize {
return Err("longer than 256 characters".into());
}
if value.chars().count() < 16usize {
return Err("shorter than 16 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ResponseChallenge {
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 ResponseChallenge {
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 ResponseChallenge {
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 ResponseChallenge {
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 Artifact {
algorithm: ::std::result::Result<super::ArtifactAlgorithm, ::std::string::String>,
byte_length: ::std::result::Result<::std::option::Option<u64>, ::std::string::String>,
digest: ::std::result::Result<super::ArtifactDigest, ::std::string::String>,
}
impl ::std::default::Default for Artifact {
fn default() -> Self {
Self {
algorithm: Err("no value supplied for algorithm".to_string()),
byte_length: Ok(Default::default()),
digest: Err("no value supplied for digest".to_string()),
}
}
}
impl Artifact {
pub fn algorithm<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ArtifactAlgorithm>,
T::Error: ::std::fmt::Display,
{
self.algorithm = value
.try_into()
.map_err(|e| format!("error converting supplied value for algorithm: {e}"));
self
}
pub fn byte_length<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<u64>>,
T::Error: ::std::fmt::Display,
{
self.byte_length = value
.try_into()
.map_err(|e| format!("error converting supplied value for byte_length: {e}"));
self
}
pub fn digest<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ArtifactDigest>,
T::Error: ::std::fmt::Display,
{
self.digest = value
.try_into()
.map_err(|e| format!("error converting supplied value for digest: {e}"));
self
}
}
impl ::std::convert::TryFrom<Artifact> for super::Artifact {
type Error = super::error::ConversionError;
fn try_from(value: Artifact) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
algorithm: value.algorithm?,
byte_length: value.byte_length?,
digest: value.digest?,
})
}
}
impl ::std::convert::From<super::Artifact> for Artifact {
fn from(value: super::Artifact) -> Self {
Self {
algorithm: Ok(value.algorithm),
byte_length: Ok(value.byte_length),
digest: Ok(value.digest),
}
}
}
#[derive(Clone, Debug)]
pub struct Assessment {
confidence: ::std::result::Result<::std::option::Option<i64>, ::std::string::String>,
determination: ::std::result::Result<super::AssessmentDetermination, ::std::string::String>,
primitive: ::std::result::Result<::std::string::String, ::std::string::String>,
}
impl ::std::default::Default for Assessment {
fn default() -> Self {
Self {
confidence: Ok(Default::default()),
determination: Err("no value supplied for determination".to_string()),
primitive: Err("no value supplied for primitive".to_string()),
}
}
}
impl Assessment {
pub fn confidence<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<i64>>,
T::Error: ::std::fmt::Display,
{
self.confidence = value
.try_into()
.map_err(|e| format!("error converting supplied value for confidence: {e}"));
self
}
pub fn determination<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::AssessmentDetermination>,
T::Error: ::std::fmt::Display,
{
self.determination = value
.try_into()
.map_err(|e| format!("error converting supplied value for determination: {e}"));
self
}
pub fn primitive<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::string::String>,
T::Error: ::std::fmt::Display,
{
self.primitive = value
.try_into()
.map_err(|e| format!("error converting supplied value for primitive: {e}"));
self
}
}
impl ::std::convert::TryFrom<Assessment> for super::Assessment {
type Error = super::error::ConversionError;
fn try_from(
value: Assessment,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
confidence: value.confidence?,
determination: value.determination?,
primitive: value.primitive?,
})
}
}
impl ::std::convert::From<super::Assessment> for Assessment {
fn from(value: super::Assessment) -> Self {
Self {
confidence: Ok(value.confidence),
determination: Ok(value.determination),
primitive: Ok(value.primitive),
}
}
}
#[derive(Clone, Debug)]
pub struct Disclosed {
anchors: ::std::result::Result<
::std::vec::Vec<super::DisclosedAnchorsItem>,
::std::string::String,
>,
document: ::std::result::Result<
::std::option::Option<super::DisclosedDocument>,
::std::string::String,
>,
integrity: ::std::result::Result<
::std::option::Option<super::DisclosedIntegrity>,
::std::string::String,
>,
timeline: ::std::result::Result<
::std::option::Option<super::DisclosedTimeline>,
::std::string::String,
>,
}
impl ::std::default::Default for Disclosed {
fn default() -> Self {
Self {
anchors: Ok(Default::default()),
document: Ok(Default::default()),
integrity: Ok(Default::default()),
timeline: Ok(Default::default()),
}
}
}
impl Disclosed {
pub fn anchors<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::vec::Vec<super::DisclosedAnchorsItem>>,
T::Error: ::std::fmt::Display,
{
self.anchors = value
.try_into()
.map_err(|e| format!("error converting supplied value for anchors: {e}"));
self
}
pub fn document<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::DisclosedDocument>>,
T::Error: ::std::fmt::Display,
{
self.document = value
.try_into()
.map_err(|e| format!("error converting supplied value for document: {e}"));
self
}
pub fn integrity<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::DisclosedIntegrity>>,
T::Error: ::std::fmt::Display,
{
self.integrity = value
.try_into()
.map_err(|e| format!("error converting supplied value for integrity: {e}"));
self
}
pub fn timeline<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::DisclosedTimeline>>,
T::Error: ::std::fmt::Display,
{
self.timeline = value
.try_into()
.map_err(|e| format!("error converting supplied value for timeline: {e}"));
self
}
}
impl ::std::convert::TryFrom<Disclosed> for super::Disclosed {
type Error = super::error::ConversionError;
fn try_from(
value: Disclosed,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
anchors: value.anchors?,
document: value.document?,
integrity: value.integrity?,
timeline: value.timeline?,
})
}
}
impl ::std::convert::From<super::Disclosed> for Disclosed {
fn from(value: super::Disclosed) -> Self {
Self {
anchors: Ok(value.anchors),
document: Ok(value.document),
integrity: Ok(value.integrity),
timeline: Ok(value.timeline),
}
}
}
#[derive(Clone, Debug)]
pub struct DisclosedAnchorsItem {
anchored_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
kind: ::std::result::Result<super::DisclosedAnchorsItemKind, ::std::string::String>,
}
impl ::std::default::Default for DisclosedAnchorsItem {
fn default() -> Self {
Self {
anchored_at: Ok(Default::default()),
kind: Err("no value supplied for kind".to_string()),
}
}
}
impl DisclosedAnchorsItem {
pub fn anchored_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.anchored_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for anchored_at: {e}"));
self
}
pub fn kind<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::DisclosedAnchorsItemKind>,
T::Error: ::std::fmt::Display,
{
self.kind = value
.try_into()
.map_err(|e| format!("error converting supplied value for kind: {e}"));
self
}
}
impl ::std::convert::TryFrom<DisclosedAnchorsItem> for super::DisclosedAnchorsItem {
type Error = super::error::ConversionError;
fn try_from(
value: DisclosedAnchorsItem,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
anchored_at: value.anchored_at?,
kind: value.kind?,
})
}
}
impl ::std::convert::From<super::DisclosedAnchorsItem> for DisclosedAnchorsItem {
fn from(value: super::DisclosedAnchorsItem) -> Self {
Self {
anchored_at: Ok(value.anchored_at),
kind: Ok(value.kind),
}
}
}
#[derive(Clone, Debug)]
pub struct DisclosedDocument {
media_type: ::std::result::Result<
::std::option::Option<super::DisclosedDocumentMediaType>,
::std::string::String,
>,
}
impl ::std::default::Default for DisclosedDocument {
fn default() -> Self {
Self {
media_type: Ok(Default::default()),
}
}
}
impl DisclosedDocument {
pub fn media_type<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::DisclosedDocumentMediaType>>,
T::Error: ::std::fmt::Display,
{
self.media_type = value
.try_into()
.map_err(|e| format!("error converting supplied value for media_type: {e}"));
self
}
}
impl ::std::convert::TryFrom<DisclosedDocument> for super::DisclosedDocument {
type Error = super::error::ConversionError;
fn try_from(
value: DisclosedDocument,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
media_type: value.media_type?,
})
}
}
impl ::std::convert::From<super::DisclosedDocument> for DisclosedDocument {
fn from(value: super::DisclosedDocument) -> Self {
Self {
media_type: Ok(value.media_type),
}
}
}
#[derive(Clone, Debug)]
pub struct DisclosedIntegrity {
chain_valid: ::std::result::Result<::std::option::Option<bool>, ::std::string::String>,
key_custody: ::std::result::Result<
::std::option::Option<super::DisclosedIntegrityKeyCustody>,
::std::string::String,
>,
signature_valid: ::std::result::Result<::std::option::Option<bool>, ::std::string::String>,
}
impl ::std::default::Default for DisclosedIntegrity {
fn default() -> Self {
Self {
chain_valid: Ok(Default::default()),
key_custody: Ok(Default::default()),
signature_valid: Ok(Default::default()),
}
}
}
impl DisclosedIntegrity {
pub fn chain_valid<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<bool>>,
T::Error: ::std::fmt::Display,
{
self.chain_valid = value
.try_into()
.map_err(|e| format!("error converting supplied value for chain_valid: {e}"));
self
}
pub fn key_custody<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::DisclosedIntegrityKeyCustody>>,
T::Error: ::std::fmt::Display,
{
self.key_custody = value
.try_into()
.map_err(|e| format!("error converting supplied value for key_custody: {e}"));
self
}
pub fn signature_valid<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<bool>>,
T::Error: ::std::fmt::Display,
{
self.signature_valid = value
.try_into()
.map_err(|e| format!("error converting supplied value for signature_valid: {e}"));
self
}
}
impl ::std::convert::TryFrom<DisclosedIntegrity> for super::DisclosedIntegrity {
type Error = super::error::ConversionError;
fn try_from(
value: DisclosedIntegrity,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
chain_valid: value.chain_valid?,
key_custody: value.key_custody?,
signature_valid: value.signature_valid?,
})
}
}
impl ::std::convert::From<super::DisclosedIntegrity> for DisclosedIntegrity {
fn from(value: super::DisclosedIntegrity) -> Self {
Self {
chain_valid: Ok(value.chain_valid),
key_custody: Ok(value.key_custody),
signature_valid: Ok(value.signature_valid),
}
}
}
#[derive(Clone, Debug)]
pub struct DisclosedTimeline {
checkpoint_count: ::std::result::Result<::std::option::Option<u64>, ::std::string::String>,
ended_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
started_at: ::std::result::Result<
::std::option::Option<::chrono::DateTime<::chrono::offset::Utc>>,
::std::string::String,
>,
}
impl ::std::default::Default for DisclosedTimeline {
fn default() -> Self {
Self {
checkpoint_count: Ok(Default::default()),
ended_at: Ok(Default::default()),
started_at: Ok(Default::default()),
}
}
}
impl DisclosedTimeline {
pub fn checkpoint_count<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<u64>>,
T::Error: ::std::fmt::Display,
{
self.checkpoint_count = value
.try_into()
.map_err(|e| format!("error converting supplied value for checkpoint_count: {e}"));
self
}
pub fn ended_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.ended_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for ended_at: {e}"));
self
}
pub fn started_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.started_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for started_at: {e}"));
self
}
}
impl ::std::convert::TryFrom<DisclosedTimeline> for super::DisclosedTimeline {
type Error = super::error::ConversionError;
fn try_from(
value: DisclosedTimeline,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
checkpoint_count: value.checkpoint_count?,
ended_at: value.ended_at?,
started_at: value.started_at?,
})
}
}
impl ::std::convert::From<super::DisclosedTimeline> for DisclosedTimeline {
fn from(value: super::DisclosedTimeline) -> Self {
Self {
checkpoint_count: Ok(value.checkpoint_count),
ended_at: Ok(value.ended_at),
started_at: Ok(value.started_at),
}
}
}
#[derive(Clone, Debug)]
pub struct Payload {
artifact: ::std::result::Result<super::Artifact, ::std::string::String>,
challenge: ::std::result::Result<super::PayloadChallenge, ::std::string::String>,
disclosure: ::std::result::Result<
::std::option::Option<Vec<super::DisclosureCategory>>,
::std::string::String,
>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
artifact: Err("no value supplied for artifact".to_string()),
challenge: Err("no value supplied for challenge".to_string()),
disclosure: Ok(Default::default()),
ext: Ok(Default::default()),
}
}
}
impl Payload {
pub fn artifact<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::Artifact>,
T::Error: ::std::fmt::Display,
{
self.artifact = value
.try_into()
.map_err(|e| format!("error converting supplied value for artifact: {e}"));
self
}
pub fn challenge<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PayloadChallenge>,
T::Error: ::std::fmt::Display,
{
self.challenge = value
.try_into()
.map_err(|e| format!("error converting supplied value for challenge: {e}"));
self
}
pub fn disclosure<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<Vec<super::DisclosureCategory>>>,
T::Error: ::std::fmt::Display,
{
self.disclosure = value
.try_into()
.map_err(|e| format!("error converting supplied value for disclosure: {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
}
}
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 {
artifact: value.artifact?,
challenge: value.challenge?,
disclosure: value.disclosure?,
ext: value.ext?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
artifact: Ok(value.artifact),
challenge: Ok(value.challenge),
disclosure: Ok(value.disclosure),
ext: Ok(value.ext),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/process-attestation/0.1";
const IS_ISSUED_AT_REQUIRED: bool = true;
const IS_RECIPIENT_REQUIRED: bool = true;
const PAYLOAD_SCHEMA: Option<&'static str> = Some(
"{\"$defs\":{\"Artifact\":{\"additionalProperties\":false,\"description\":\"Deterministic identification of the object whose production is in question.\",\"properties\":{\"algorithm\":{\"description\":\"Carried verbatim from the IANA Named Information Hash Algorithm registry, not re-cased — SPEC §4.10 externally-owned values.\",\"enum\":[\"sha-256\",\"sha-384\",\"sha-512\",\"blake3\"],\"type\":\"string\"},\"byteLength\":{\"minimum\":0,\"type\":\"integer\"},\"digest\":{\"description\":\"base64url, unpadded.\",\"pattern\":\"^[A-Za-z0-9_-]{43,128}$\",\"type\":\"string\"}},\"required\":[\"digest\",\"algorithm\"],\"type\":\"object\"},\"Assessment\":{\"additionalProperties\":false,\"description\":\"Opaque at the task layer. The task standardizes the interaction, not the receipt.\",\"properties\":{\"confidence\":{\"description\":\"The primitive's confidence in `determination`, as an integer percentage. An integer rather than a fraction because no other specification in this registry puts a floating-point value on the wire: a float's textual form is not stable across JSON implementations, which makes byte-exact re-serialization a language-dependent property.\",\"maximum\":100,\"minimum\":0,\"type\":\"integer\"},\"determination\":{\"description\":\"Primitive-defined. Deliberately not normalized across primitives: a determination means only what the primitive that produced it defines it to mean.\",\"maxLength\":128,\"minLength\":1,\"type\":\"string\"},\"primitive\":{\"description\":\"Specification the receipt is verified under. Names which vocabulary `determination` belongs to.\",\"format\":\"uri\",\"maxLength\":2048,\"type\":\"string\"}},\"required\":[\"primitive\",\"determination\"],\"type\":\"object\"},\"Disclosed\":{\"additionalProperties\":false,\"description\":\"Only the categories the request asked for.\",\"properties\":{\"anchors\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"anchoredAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"kind\":{\"enum\":[\"rfc3161\",\"opentimestamps\",\"roughtime\"],\"type\":\"string\"}},\"required\":[\"kind\"],\"type\":\"object\"},\"type\":\"array\"},\"document\":{\"additionalProperties\":false,\"properties\":{\"mediaType\":{\"maxLength\":255,\"type\":\"string\"}},\"type\":\"object\"},\"integrity\":{\"additionalProperties\":false,\"properties\":{\"chainValid\":{\"type\":\"boolean\"},\"keyCustody\":{\"enum\":[\"software\",\"tpm\",\"secureEnclave\"],\"type\":\"string\"},\"signatureValid\":{\"type\":\"boolean\"}},\"type\":\"object\"},\"timeline\":{\"additionalProperties\":false,\"properties\":{\"checkpointCount\":{\"minimum\":0,\"type\":\"integer\"},\"endedAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"startedAt\":{\"format\":\"date-time\",\"type\":\"string\"}},\"type\":\"object\"}},\"type\":\"object\"},\"DisclosureCategory\":{\"description\":\"Derived aggregates only. An enum rather than a pattern so a primitive cannot widen its own disclosure surface by inventing a name. The determination itself is not a category: it is always in `assessment` when the result is `attested`. Raw behavioral samples and fingerprints are out of scope for 0.1.\",\"enum\":[\"document\",\"timeline\",\"integrity\",\"anchors\"],\"type\":\"string\"},\"Ext\":{\"additionalProperties\":true,\"description\":\"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\"minProperties\":1,\"propertyNames\":{\"pattern\":\"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"},\"title\":\"Ext\",\"type\":\"object\"},\"ReceiptReference\":{\"description\":\"Tagged union. Inline exists for Verifiers that cannot dereference a URI at verification time.\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"mediaType\":{\"maxLength\":255,\"type\":\"string\"},\"type\":{\"const\":\"uri\"},\"uri\":{\"format\":\"uri\",\"maxLength\":2048,\"type\":\"string\"}},\"required\":[\"type\",\"uri\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"data\":{\"description\":\"base64url, unpadded. Bounded at 256 KiB of encoded text (~192 KiB of receipt): inline exists for the offline case, not as the general transport. A receipt larger than the bound MUST use the `uri` form.\",\"maxLength\":262144,\"pattern\":\"^[A-Za-z0-9_-]+$\",\"type\":\"string\"},\"mediaType\":{\"maxLength\":255,\"type\":\"string\"},\"type\":{\"const\":\"inline\"}},\"required\":[\"type\",\"mediaType\",\"data\"],\"type\":\"object\"}]},\"Response\":{\"$anchor\":\"response\",\"description\":\"The Holder's answer. Failures use trust-task-error, not this shape. Both results share one response type so the envelope carries no observable distinction between them. `result` is the discriminator and stays inside the payload, so one envelope type covers both branches.\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"artifact\":{\"$ref\":\"#/$defs/Artifact\"},\"assessment\":{\"$ref\":\"#/$defs/Assessment\"},\"challenge\":{\"description\":\"The request's challenge, echoed verbatim.\",\"maxLength\":256,\"minLength\":16,\"type\":\"string\"},\"disclosed\":{\"$ref\":\"#/$defs/Disclosed\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"receiptReference\":{\"$ref\":\"#/$defs/ReceiptReference\"},\"result\":{\"const\":\"attested\"}},\"required\":[\"result\",\"challenge\",\"artifact\",\"assessment\",\"receiptReference\"],\"title\":\"Attested\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"artifact\":{\"$ref\":\"#/$defs/Artifact\"},\"challenge\":{\"description\":\"The request's challenge, echoed verbatim.\",\"maxLength\":256,\"minLength\":16,\"type\":\"string\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"result\":{\"const\":\"unavailable\"}},\"required\":[\"result\",\"challenge\",\"artifact\"],\"title\":\"Unavailable\",\"type\":\"object\"}],\"title\":\"Process Attestation — response payload\",\"unevaluatedProperties\":false}},\"$id\":\"https://trusttasks.org/spec/process-attestation/0.1\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"additionalProperties\":false,\"description\":\"What a Verifier asks of a Holder: identify an artifact by digest, supply a freshness challenge, and name the disclosure categories wanted. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, proof) are owned by the framework — SPEC §6.3.\",\"properties\":{\"artifact\":{\"$ref\":\"#/$defs/Artifact\"},\"challenge\":{\"description\":\"Verifier-supplied freshness nonce, echoed verbatim in the response. The floor is 16 characters because anti-replay is the only integrity property the request has.\",\"maxLength\":256,\"minLength\":16,\"type\":\"string\"},\"disclosure\":{\"description\":\"Categories the Verifier requests. A Holder MAY return fewer; it MUST NOT return more.\",\"items\":{\"$ref\":\"#/$defs/DisclosureCategory\"},\"type\":\"array\",\"uniqueItems\":true},\"ext\":{\"$ref\":\"#/$defs/Ext\"}},\"required\":[\"artifact\",\"challenge\"],\"title\":\"Process Attestation — payload\",\"type\":\"object\"}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/process-attestation/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(
"{\"$defs\":{\"Artifact\":{\"additionalProperties\":false,\"description\":\"Deterministic identification of the object whose production is in question.\",\"properties\":{\"algorithm\":{\"description\":\"Carried verbatim from the IANA Named Information Hash Algorithm registry, not re-cased — SPEC §4.10 externally-owned values.\",\"enum\":[\"sha-256\",\"sha-384\",\"sha-512\",\"blake3\"],\"type\":\"string\"},\"byteLength\":{\"minimum\":0,\"type\":\"integer\"},\"digest\":{\"description\":\"base64url, unpadded.\",\"pattern\":\"^[A-Za-z0-9_-]{43,128}$\",\"type\":\"string\"}},\"required\":[\"digest\",\"algorithm\"],\"type\":\"object\"},\"Assessment\":{\"additionalProperties\":false,\"description\":\"Opaque at the task layer. The task standardizes the interaction, not the receipt.\",\"properties\":{\"confidence\":{\"description\":\"The primitive's confidence in `determination`, as an integer percentage. An integer rather than a fraction because no other specification in this registry puts a floating-point value on the wire: a float's textual form is not stable across JSON implementations, which makes byte-exact re-serialization a language-dependent property.\",\"maximum\":100,\"minimum\":0,\"type\":\"integer\"},\"determination\":{\"description\":\"Primitive-defined. Deliberately not normalized across primitives: a determination means only what the primitive that produced it defines it to mean.\",\"maxLength\":128,\"minLength\":1,\"type\":\"string\"},\"primitive\":{\"description\":\"Specification the receipt is verified under. Names which vocabulary `determination` belongs to.\",\"format\":\"uri\",\"maxLength\":2048,\"type\":\"string\"}},\"required\":[\"primitive\",\"determination\"],\"type\":\"object\"},\"Disclosed\":{\"additionalProperties\":false,\"description\":\"Only the categories the request asked for.\",\"properties\":{\"anchors\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"anchoredAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"kind\":{\"enum\":[\"rfc3161\",\"opentimestamps\",\"roughtime\"],\"type\":\"string\"}},\"required\":[\"kind\"],\"type\":\"object\"},\"type\":\"array\"},\"document\":{\"additionalProperties\":false,\"properties\":{\"mediaType\":{\"maxLength\":255,\"type\":\"string\"}},\"type\":\"object\"},\"integrity\":{\"additionalProperties\":false,\"properties\":{\"chainValid\":{\"type\":\"boolean\"},\"keyCustody\":{\"enum\":[\"software\",\"tpm\",\"secureEnclave\"],\"type\":\"string\"},\"signatureValid\":{\"type\":\"boolean\"}},\"type\":\"object\"},\"timeline\":{\"additionalProperties\":false,\"properties\":{\"checkpointCount\":{\"minimum\":0,\"type\":\"integer\"},\"endedAt\":{\"format\":\"date-time\",\"type\":\"string\"},\"startedAt\":{\"format\":\"date-time\",\"type\":\"string\"}},\"type\":\"object\"}},\"type\":\"object\"},\"DisclosureCategory\":{\"description\":\"Derived aggregates only. An enum rather than a pattern so a primitive cannot widen its own disclosure surface by inventing a name. The determination itself is not a category: it is always in `assessment` when the result is `attested`. Raw behavioral samples and fingerprints are out of scope for 0.1.\",\"enum\":[\"document\",\"timeline\",\"integrity\",\"anchors\"],\"type\":\"string\"},\"Ext\":{\"additionalProperties\":true,\"description\":\"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\"minProperties\":1,\"propertyNames\":{\"pattern\":\"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"},\"title\":\"Ext\",\"type\":\"object\"},\"ReceiptReference\":{\"description\":\"Tagged union. Inline exists for Verifiers that cannot dereference a URI at verification time.\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"mediaType\":{\"maxLength\":255,\"type\":\"string\"},\"type\":{\"const\":\"uri\"},\"uri\":{\"format\":\"uri\",\"maxLength\":2048,\"type\":\"string\"}},\"required\":[\"type\",\"uri\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"data\":{\"description\":\"base64url, unpadded. Bounded at 256 KiB of encoded text (~192 KiB of receipt): inline exists for the offline case, not as the general transport. A receipt larger than the bound MUST use the `uri` form.\",\"maxLength\":262144,\"pattern\":\"^[A-Za-z0-9_-]+$\",\"type\":\"string\"},\"mediaType\":{\"maxLength\":255,\"type\":\"string\"},\"type\":{\"const\":\"inline\"}},\"required\":[\"type\",\"mediaType\",\"data\"],\"type\":\"object\"}]},\"Response\":{\"$anchor\":\"response\",\"description\":\"The Holder's answer. Failures use trust-task-error, not this shape. Both results share one response type so the envelope carries no observable distinction between them. `result` is the discriminator and stays inside the payload, so one envelope type covers both branches.\",\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"artifact\":{\"$ref\":\"#/$defs/Artifact\"},\"assessment\":{\"$ref\":\"#/$defs/Assessment\"},\"challenge\":{\"description\":\"The request's challenge, echoed verbatim.\",\"maxLength\":256,\"minLength\":16,\"type\":\"string\"},\"disclosed\":{\"$ref\":\"#/$defs/Disclosed\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"receiptReference\":{\"$ref\":\"#/$defs/ReceiptReference\"},\"result\":{\"const\":\"attested\"}},\"required\":[\"result\",\"challenge\",\"artifact\",\"assessment\",\"receiptReference\"],\"title\":\"Attested\",\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"artifact\":{\"$ref\":\"#/$defs/Artifact\"},\"challenge\":{\"description\":\"The request's challenge, echoed verbatim.\",\"maxLength\":256,\"minLength\":16,\"type\":\"string\"},\"ext\":{\"$ref\":\"#/$defs/Ext\"},\"result\":{\"const\":\"unavailable\"}},\"required\":[\"result\",\"challenge\",\"artifact\"],\"title\":\"Unavailable\",\"type\":\"object\"}],\"title\":\"Process Attestation — response payload\",\"unevaluatedProperties\":false}},\"$ref\":\"#/$defs/Response\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\"}\n",
);
}
impl crate::RequestPayload for Payload {
type Response = Response;
}
/// The earlier `MAJOR.MINOR` of this slug that this version declares it
/// extends (front matter `extends`, SPEC §5.2 "Declared extension"), or
/// `None`. Only the direct declaration; walk a chain with
/// [`crate::extension::extends_for`].
pub const EXTENDS: Option<&str> = None;
/// The extended error codes this specification declares (SPEC §7.3 item 9,
/// §8.5), in declaration order. Empty when it declares none.
pub const ERROR_CODES: &[crate::DeclaredErrorCode] = &[];