//! Generated by `trust-tasks-codegen` — do not edit by hand.
//!
//! Spec slug: `vtc/backup/import`. 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())
}
}
}
///Unencrypted metadata plus the encrypted payload. The KDF and cipher parameters travel in the clear so a reader can decrypt without knowing this specification's defaults.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "BackupEnvelope",
/// "description": "Unencrypted metadata plus the encrypted payload. The KDF and cipher parameters travel in the clear so a reader can decrypt without knowing this specification's defaults.",
/// "type": "object",
/// "required": [
/// "ciphertext",
/// "createdAt",
/// "encryption",
/// "format",
/// "includesAudit",
/// "kdf",
/// "sourceVersion",
/// "version"
/// ],
/// "properties": {
/// "ciphertext": {
/// "description": "base64url(AEAD(JSON(payload))).",
/// "type": "string",
/// "minLength": 1
/// },
/// "createdAt": {
/// "description": "When the export was taken.",
/// "type": "string",
/// "format": "date-time"
/// },
/// "encryption": {
/// "$ref": "#/definitions/EncryptionParams"
/// },
/// "format": {
/// "description": "Envelope format tag, e.g. `vtc-backup-v1`.",
/// "type": "string",
/// "minLength": 1
/// },
/// "includesAudit": {
/// "description": "Whether the audit log and its signed checkpoints are inside `ciphertext`.",
/// "type": "boolean"
/// },
/// "kdf": {
/// "$ref": "#/definitions/KdfParams"
/// },
/// "sourceDid": {
/// "description": "DID of the community exported from, when it has one. An import cross-checks this against the running community.",
/// "type": [
/// "string",
/// "null"
/// ]
/// },
/// "sourceVersion": {
/// "description": "Version of the software that produced the envelope.",
/// "type": "string",
/// "minLength": 1
/// },
/// "version": {
/// "description": "Envelope schema version.",
/// "type": "integer",
/// "minimum": 1.0
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "backupEnvelope"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct BackupEnvelope {
///base64url(AEAD(JSON(payload))).
pub ciphertext: BackupEnvelopeCiphertext,
///When the export was taken.
#[serde(rename = "createdAt")]
pub created_at: ::chrono::DateTime<::chrono::offset::Utc>,
pub encryption: EncryptionParams,
///Envelope format tag, e.g. `vtc-backup-v1`.
pub format: BackupEnvelopeFormat,
///Whether the audit log and its signed checkpoints are inside `ciphertext`.
#[serde(rename = "includesAudit")]
pub includes_audit: bool,
pub kdf: KdfParams,
///DID of the community exported from, when it has one. An import cross-checks this against the running community.
#[serde(
rename = "sourceDid",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub source_did: ::std::option::Option<::std::string::String>,
///Version of the software that produced the envelope.
#[serde(rename = "sourceVersion")]
pub source_version: BackupEnvelopeSourceVersion,
///Envelope schema version.
pub version: ::std::num::NonZeroU64,
}
impl BackupEnvelope {
pub fn builder() -> builder::BackupEnvelope {
Default::default()
}
}
///base64url(AEAD(JSON(payload))).
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "base64url(AEAD(JSON(payload))).",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct BackupEnvelopeCiphertext(::std::string::String);
impl ::std::ops::Deref for BackupEnvelopeCiphertext {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<BackupEnvelopeCiphertext> for ::std::string::String {
fn from(value: BackupEnvelopeCiphertext) -> Self {
value.0
}
}
impl ::std::str::FromStr for BackupEnvelopeCiphertext {
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 BackupEnvelopeCiphertext {
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 BackupEnvelopeCiphertext {
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 BackupEnvelopeCiphertext {
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 BackupEnvelopeCiphertext {
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())
})
}
}
///Envelope format tag, e.g. `vtc-backup-v1`.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Envelope format tag, e.g. `vtc-backup-v1`.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct BackupEnvelopeFormat(::std::string::String);
impl ::std::ops::Deref for BackupEnvelopeFormat {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<BackupEnvelopeFormat> for ::std::string::String {
fn from(value: BackupEnvelopeFormat) -> Self {
value.0
}
}
impl ::std::str::FromStr for BackupEnvelopeFormat {
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 BackupEnvelopeFormat {
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 BackupEnvelopeFormat {
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 BackupEnvelopeFormat {
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 BackupEnvelopeFormat {
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())
})
}
}
///Version of the software that produced the envelope.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Version of the software that produced the envelope.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct BackupEnvelopeSourceVersion(::std::string::String);
impl ::std::ops::Deref for BackupEnvelopeSourceVersion {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<BackupEnvelopeSourceVersion> for ::std::string::String {
fn from(value: BackupEnvelopeSourceVersion) -> Self {
value.0
}
}
impl ::std::str::FromStr for BackupEnvelopeSourceVersion {
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 BackupEnvelopeSourceVersion {
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 BackupEnvelopeSourceVersion {
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 BackupEnvelopeSourceVersion {
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 BackupEnvelopeSourceVersion {
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())
})
}
}
///`EncryptionParams`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "EncryptionParams",
/// "type": "object",
/// "required": [
/// "algorithm",
/// "nonce"
/// ],
/// "properties": {
/// "algorithm": {
/// "description": "AEAD identifier, e.g. `aes-256-gcm`.",
/// "type": "string",
/// "minLength": 1
/// },
/// "nonce": {
/// "description": "base64url, 12 bytes.",
/// "type": "string",
/// "minLength": 1
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "encryptionParams"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct EncryptionParams {
///AEAD identifier, e.g. `aes-256-gcm`.
pub algorithm: EncryptionParamsAlgorithm,
///base64url, 12 bytes.
pub nonce: EncryptionParamsNonce,
}
impl EncryptionParams {
pub fn builder() -> builder::EncryptionParams {
Default::default()
}
}
///AEAD identifier, e.g. `aes-256-gcm`.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "AEAD identifier, e.g. `aes-256-gcm`.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct EncryptionParamsAlgorithm(::std::string::String);
impl ::std::ops::Deref for EncryptionParamsAlgorithm {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<EncryptionParamsAlgorithm> for ::std::string::String {
fn from(value: EncryptionParamsAlgorithm) -> Self {
value.0
}
}
impl ::std::str::FromStr for EncryptionParamsAlgorithm {
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 EncryptionParamsAlgorithm {
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 EncryptionParamsAlgorithm {
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 EncryptionParamsAlgorithm {
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 EncryptionParamsAlgorithm {
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())
})
}
}
///base64url, 12 bytes.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "base64url, 12 bytes.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct EncryptionParamsNonce(::std::string::String);
impl ::std::ops::Deref for EncryptionParamsNonce {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<EncryptionParamsNonce> for ::std::string::String {
fn from(value: EncryptionParamsNonce) -> Self {
value.0
}
}
impl ::std::str::FromStr for EncryptionParamsNonce {
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 EncryptionParamsNonce {
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 EncryptionParamsNonce {
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 EncryptionParamsNonce {
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 EncryptionParamsNonce {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Ext",
/// "description": "Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.",
/// "type": "object",
/// "minProperties": 1,
/// "additionalProperties": true,
/// "propertyNames": {
/// "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
/// }
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct Ext(pub ::std::collections::HashMap<ExtKey, ::serde_json::Value>);
impl ::std::ops::Deref for Ext {
type Target = ::std::collections::HashMap<ExtKey, ::serde_json::Value>;
fn deref(&self) -> &::std::collections::HashMap<ExtKey, ::serde_json::Value> {
&self.0
}
}
impl ::std::convert::From<Ext> for ::std::collections::HashMap<ExtKey, ::serde_json::Value> {
fn from(value: Ext) -> Self {
value.0
}
}
impl ::std::convert::From<::std::collections::HashMap<ExtKey, ::serde_json::Value>> for Ext {
fn from(value: ::std::collections::HashMap<ExtKey, ::serde_json::Value>) -> Self {
Self(value)
}
}
///`ExtKey`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "type": "string",
/// "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ExtKey(::std::string::String);
impl ::std::ops::Deref for ExtKey {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ExtKey> for ::std::string::String {
fn from(value: ExtKey) -> Self {
value.0
}
}
impl ::std::str::FromStr for ExtKey {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
static PATTERN: ::std::sync::LazyLock<::regress::Regex> =
::std::sync::LazyLock::new(|| {
::regress::Regex::new("^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$").unwrap()
});
if PATTERN.find(value).is_none() {
return Err("doesn't match pattern \"^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$\"".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ExtKey {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl<'de> ::serde::Deserialize<'de> for ExtKey {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`KdfParams`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "KdfParams",
/// "type": "object",
/// "required": [
/// "algorithm",
/// "mCost",
/// "pCost",
/// "salt",
/// "tCost"
/// ],
/// "properties": {
/// "algorithm": {
/// "description": "KDF identifier, e.g. `argon2id`.",
/// "type": "string",
/// "minLength": 1
/// },
/// "mCost": {
/// "description": "Argon2id memory cost (KiB).",
/// "type": "integer",
/// "minimum": 1.0
/// },
/// "pCost": {
/// "description": "Argon2id parallelism.",
/// "type": "integer",
/// "minimum": 1.0
/// },
/// "salt": {
/// "description": "base64url, 32 bytes.",
/// "type": "string",
/// "minLength": 1
/// },
/// "tCost": {
/// "description": "Argon2id time cost (iterations).",
/// "type": "integer",
/// "minimum": 1.0
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "kdfParams"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct KdfParams {
///KDF identifier, e.g. `argon2id`.
pub algorithm: KdfParamsAlgorithm,
///Argon2id memory cost (KiB).
#[serde(rename = "mCost")]
pub m_cost: ::std::num::NonZeroU64,
///Argon2id parallelism.
#[serde(rename = "pCost")]
pub p_cost: ::std::num::NonZeroU64,
///base64url, 32 bytes.
pub salt: KdfParamsSalt,
///Argon2id time cost (iterations).
#[serde(rename = "tCost")]
pub t_cost: ::std::num::NonZeroU64,
}
impl KdfParams {
pub fn builder() -> builder::KdfParams {
Default::default()
}
}
///KDF identifier, e.g. `argon2id`.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "KDF identifier, e.g. `argon2id`.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct KdfParamsAlgorithm(::std::string::String);
impl ::std::ops::Deref for KdfParamsAlgorithm {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<KdfParamsAlgorithm> for ::std::string::String {
fn from(value: KdfParamsAlgorithm) -> Self {
value.0
}
}
impl ::std::str::FromStr for KdfParamsAlgorithm {
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 KdfParamsAlgorithm {
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 KdfParamsAlgorithm {
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 KdfParamsAlgorithm {
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 KdfParamsAlgorithm {
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())
})
}
}
///base64url, 32 bytes.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "base64url, 32 bytes.",
/// "type": "string",
/// "minLength": 1
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct KdfParamsSalt(::std::string::String);
impl ::std::ops::Deref for KdfParamsSalt {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<KdfParamsSalt> for ::std::string::String {
fn from(value: KdfParamsSalt) -> Self {
value.0
}
}
impl ::std::str::FromStr for KdfParamsSalt {
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 KdfParamsSalt {
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 KdfParamsSalt {
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 KdfParamsSalt {
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 KdfParamsSalt {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`Payload`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "$id": "https://trusttasks.org/spec/vtc/backup/import/0.1",
/// "title": "Payload",
/// "type": "object",
/// "required": [
/// "backup",
/// "password"
/// ],
/// "properties": {
/// "backup": {
/// "description": "The envelope returned by `vtc/backup/export`.",
/// "$ref": "#/definitions/BackupEnvelope"
/// },
/// "confirm": {
/// "description": "`false` (default) previews: row counts, no mutation. `true` clears the backed-up keyspaces and applies the backup.",
/// "default": false,
/// "type": "boolean"
/// },
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "password": {
/// "description": "The passphrase the envelope was encrypted under.",
/// "type": "string",
/// "minLength": 12
/// }
/// },
/// "additionalProperties": false
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Payload {
///The envelope returned by `vtc/backup/export`.
pub backup: BackupEnvelope,
///`false` (default) previews: row counts, no mutation. `true` clears the backed-up keyspaces and applies the backup.
#[serde(default)]
pub confirm: bool,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///The passphrase the envelope was encrypted under.
pub password: PayloadPassword,
}
impl Payload {
pub fn builder() -> builder::Payload {
Default::default()
}
}
///The passphrase the envelope was encrypted under.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "The passphrase the envelope was encrypted under.",
/// "type": "string",
/// "minLength": 12
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct PayloadPassword(::std::string::String);
impl ::std::ops::Deref for PayloadPassword {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<PayloadPassword> for ::std::string::String {
fn from(value: PayloadPassword) -> Self {
value.0
}
}
impl ::std::str::FromStr for PayloadPassword {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.chars().count() < 12usize {
return Err("shorter than 12 characters".into());
}
Ok(Self(value.to_string()))
}
}
impl ::std::convert::TryFrom<&str> for PayloadPassword {
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 PayloadPassword {
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 PayloadPassword {
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 PayloadPassword {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
::std::string::String::deserialize(deserializer)?
.parse()
.map_err(|e: self::error::ConversionError| {
<D::Error as ::serde::de::Error>::custom(e.to_string())
})
}
}
///`Response`
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "title": "Response",
/// "type": "object",
/// "required": [
/// "counts",
/// "message",
/// "status"
/// ],
/// "properties": {
/// "counts": {
/// "description": "Per-keyspace row counts written, or that would be written on a preview.",
/// "type": "object",
/// "additionalProperties": {
/// "type": "integer",
/// "minimum": 0.0
/// }
/// },
/// "ext": {
/// "$ref": "#/definitions/Ext"
/// },
/// "message": {
/// "description": "Human-readable summary for the operator.",
/// "type": "string",
/// "maxLength": 1024
/// },
/// "sourceDid": {
/// "description": "The community DID the envelope was taken from.",
/// "type": [
/// "string",
/// "null"
/// ]
/// },
/// "status": {
/// "description": "`preview` when `confirm` was not set; `imported` after a restore.",
/// "type": "string",
/// "enum": [
/// "preview",
/// "imported"
/// ]
/// }
/// },
/// "additionalProperties": false,
/// "$anchor": "response"
///}
/// ```
/// </details>
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Response {
///Per-keyspace row counts written, or that would be written on a preview.
pub counts: ::std::collections::HashMap<::std::string::String, u64>,
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub ext: ::std::option::Option<Ext>,
///Human-readable summary for the operator.
pub message: ResponseMessage,
///The community DID the envelope was taken from.
#[serde(
rename = "sourceDid",
default,
skip_serializing_if = "::std::option::Option::is_none"
)]
pub source_did: ::std::option::Option<::std::string::String>,
///`preview` when `confirm` was not set; `imported` after a restore.
pub status: ResponseStatus,
}
impl Response {
pub fn builder() -> builder::Response {
Default::default()
}
}
///Human-readable summary for the operator.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "Human-readable summary for the operator.",
/// "type": "string",
/// "maxLength": 1024
///}
/// ```
/// </details>
#[derive(::serde::Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct ResponseMessage(::std::string::String);
impl ::std::ops::Deref for ResponseMessage {
type Target = ::std::string::String;
fn deref(&self) -> &::std::string::String {
&self.0
}
}
impl ::std::convert::From<ResponseMessage> for ::std::string::String {
fn from(value: ResponseMessage) -> Self {
value.0
}
}
impl ::std::str::FromStr for ResponseMessage {
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 ResponseMessage {
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 ResponseMessage {
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 ResponseMessage {
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 ResponseMessage {
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())
})
}
}
///`preview` when `confirm` was not set; `imported` after a restore.
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
/// "description": "`preview` when `confirm` was not set; `imported` after a restore.",
/// "type": "string",
/// "enum": [
/// "preview",
/// "imported"
/// ]
///}
/// ```
/// </details>
#[derive(
::serde::Deserialize,
::serde::Serialize,
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
)]
#[non_exhaustive]
pub enum ResponseStatus {
#[serde(rename = "preview")]
Preview,
#[serde(rename = "imported")]
Imported,
}
impl ::std::fmt::Display for ResponseStatus {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
Self::Preview => f.write_str("preview"),
Self::Imported => f.write_str("imported"),
}
}
}
impl ::std::str::FromStr for ResponseStatus {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
match value {
"preview" => Ok(Self::Preview),
"imported" => Ok(Self::Imported),
_ => Err("invalid value".into()),
}
}
}
impl ::std::convert::TryFrom<&str> for ResponseStatus {
type Error = self::error::ConversionError;
fn try_from(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<&::std::string::String> for ResponseStatus {
type Error = self::error::ConversionError;
fn try_from(
value: &::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
impl ::std::convert::TryFrom<::std::string::String> for ResponseStatus {
type Error = self::error::ConversionError;
fn try_from(
value: ::std::string::String,
) -> ::std::result::Result<Self, self::error::ConversionError> {
value.parse()
}
}
/// Types for composing complex structures.
pub mod builder {
#[derive(Clone, Debug)]
pub struct BackupEnvelope {
ciphertext: ::std::result::Result<super::BackupEnvelopeCiphertext, ::std::string::String>,
created_at:
::std::result::Result<::chrono::DateTime<::chrono::offset::Utc>, ::std::string::String>,
encryption: ::std::result::Result<super::EncryptionParams, ::std::string::String>,
format: ::std::result::Result<super::BackupEnvelopeFormat, ::std::string::String>,
includes_audit: ::std::result::Result<bool, ::std::string::String>,
kdf: ::std::result::Result<super::KdfParams, ::std::string::String>,
source_did: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
source_version:
::std::result::Result<super::BackupEnvelopeSourceVersion, ::std::string::String>,
version: ::std::result::Result<::std::num::NonZeroU64, ::std::string::String>,
}
impl ::std::default::Default for BackupEnvelope {
fn default() -> Self {
Self {
ciphertext: Err("no value supplied for ciphertext".to_string()),
created_at: Err("no value supplied for created_at".to_string()),
encryption: Err("no value supplied for encryption".to_string()),
format: Err("no value supplied for format".to_string()),
includes_audit: Err("no value supplied for includes_audit".to_string()),
kdf: Err("no value supplied for kdf".to_string()),
source_did: Ok(Default::default()),
source_version: Err("no value supplied for source_version".to_string()),
version: Err("no value supplied for version".to_string()),
}
}
}
impl BackupEnvelope {
pub fn ciphertext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::BackupEnvelopeCiphertext>,
T::Error: ::std::fmt::Display,
{
self.ciphertext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ciphertext: {e}"));
self
}
pub fn created_at<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::chrono::DateTime<::chrono::offset::Utc>>,
T::Error: ::std::fmt::Display,
{
self.created_at = value
.try_into()
.map_err(|e| format!("error converting supplied value for created_at: {e}"));
self
}
pub fn encryption<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::EncryptionParams>,
T::Error: ::std::fmt::Display,
{
self.encryption = value
.try_into()
.map_err(|e| format!("error converting supplied value for encryption: {e}"));
self
}
pub fn format<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::BackupEnvelopeFormat>,
T::Error: ::std::fmt::Display,
{
self.format = value
.try_into()
.map_err(|e| format!("error converting supplied value for format: {e}"));
self
}
pub fn includes_audit<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<bool>,
T::Error: ::std::fmt::Display,
{
self.includes_audit = value
.try_into()
.map_err(|e| format!("error converting supplied value for includes_audit: {e}"));
self
}
pub fn kdf<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::KdfParams>,
T::Error: ::std::fmt::Display,
{
self.kdf = value
.try_into()
.map_err(|e| format!("error converting supplied value for kdf: {e}"));
self
}
pub fn source_did<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.source_did = value
.try_into()
.map_err(|e| format!("error converting supplied value for source_did: {e}"));
self
}
pub fn source_version<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::BackupEnvelopeSourceVersion>,
T::Error: ::std::fmt::Display,
{
self.source_version = value
.try_into()
.map_err(|e| format!("error converting supplied value for source_version: {e}"));
self
}
pub fn version<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::num::NonZeroU64>,
T::Error: ::std::fmt::Display,
{
self.version = value
.try_into()
.map_err(|e| format!("error converting supplied value for version: {e}"));
self
}
}
impl ::std::convert::TryFrom<BackupEnvelope> for super::BackupEnvelope {
type Error = super::error::ConversionError;
fn try_from(
value: BackupEnvelope,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
ciphertext: value.ciphertext?,
created_at: value.created_at?,
encryption: value.encryption?,
format: value.format?,
includes_audit: value.includes_audit?,
kdf: value.kdf?,
source_did: value.source_did?,
source_version: value.source_version?,
version: value.version?,
})
}
}
impl ::std::convert::From<super::BackupEnvelope> for BackupEnvelope {
fn from(value: super::BackupEnvelope) -> Self {
Self {
ciphertext: Ok(value.ciphertext),
created_at: Ok(value.created_at),
encryption: Ok(value.encryption),
format: Ok(value.format),
includes_audit: Ok(value.includes_audit),
kdf: Ok(value.kdf),
source_did: Ok(value.source_did),
source_version: Ok(value.source_version),
version: Ok(value.version),
}
}
}
#[derive(Clone, Debug)]
pub struct EncryptionParams {
algorithm: ::std::result::Result<super::EncryptionParamsAlgorithm, ::std::string::String>,
nonce: ::std::result::Result<super::EncryptionParamsNonce, ::std::string::String>,
}
impl ::std::default::Default for EncryptionParams {
fn default() -> Self {
Self {
algorithm: Err("no value supplied for algorithm".to_string()),
nonce: Err("no value supplied for nonce".to_string()),
}
}
}
impl EncryptionParams {
pub fn algorithm<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::EncryptionParamsAlgorithm>,
T::Error: ::std::fmt::Display,
{
self.algorithm = value
.try_into()
.map_err(|e| format!("error converting supplied value for algorithm: {e}"));
self
}
pub fn nonce<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::EncryptionParamsNonce>,
T::Error: ::std::fmt::Display,
{
self.nonce = value
.try_into()
.map_err(|e| format!("error converting supplied value for nonce: {e}"));
self
}
}
impl ::std::convert::TryFrom<EncryptionParams> for super::EncryptionParams {
type Error = super::error::ConversionError;
fn try_from(
value: EncryptionParams,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
algorithm: value.algorithm?,
nonce: value.nonce?,
})
}
}
impl ::std::convert::From<super::EncryptionParams> for EncryptionParams {
fn from(value: super::EncryptionParams) -> Self {
Self {
algorithm: Ok(value.algorithm),
nonce: Ok(value.nonce),
}
}
}
#[derive(Clone, Debug)]
pub struct KdfParams {
algorithm: ::std::result::Result<super::KdfParamsAlgorithm, ::std::string::String>,
m_cost: ::std::result::Result<::std::num::NonZeroU64, ::std::string::String>,
p_cost: ::std::result::Result<::std::num::NonZeroU64, ::std::string::String>,
salt: ::std::result::Result<super::KdfParamsSalt, ::std::string::String>,
t_cost: ::std::result::Result<::std::num::NonZeroU64, ::std::string::String>,
}
impl ::std::default::Default for KdfParams {
fn default() -> Self {
Self {
algorithm: Err("no value supplied for algorithm".to_string()),
m_cost: Err("no value supplied for m_cost".to_string()),
p_cost: Err("no value supplied for p_cost".to_string()),
salt: Err("no value supplied for salt".to_string()),
t_cost: Err("no value supplied for t_cost".to_string()),
}
}
}
impl KdfParams {
pub fn algorithm<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::KdfParamsAlgorithm>,
T::Error: ::std::fmt::Display,
{
self.algorithm = value
.try_into()
.map_err(|e| format!("error converting supplied value for algorithm: {e}"));
self
}
pub fn m_cost<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::num::NonZeroU64>,
T::Error: ::std::fmt::Display,
{
self.m_cost = value
.try_into()
.map_err(|e| format!("error converting supplied value for m_cost: {e}"));
self
}
pub fn p_cost<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::num::NonZeroU64>,
T::Error: ::std::fmt::Display,
{
self.p_cost = value
.try_into()
.map_err(|e| format!("error converting supplied value for p_cost: {e}"));
self
}
pub fn salt<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::KdfParamsSalt>,
T::Error: ::std::fmt::Display,
{
self.salt = value
.try_into()
.map_err(|e| format!("error converting supplied value for salt: {e}"));
self
}
pub fn t_cost<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::num::NonZeroU64>,
T::Error: ::std::fmt::Display,
{
self.t_cost = value
.try_into()
.map_err(|e| format!("error converting supplied value for t_cost: {e}"));
self
}
}
impl ::std::convert::TryFrom<KdfParams> for super::KdfParams {
type Error = super::error::ConversionError;
fn try_from(
value: KdfParams,
) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
algorithm: value.algorithm?,
m_cost: value.m_cost?,
p_cost: value.p_cost?,
salt: value.salt?,
t_cost: value.t_cost?,
})
}
}
impl ::std::convert::From<super::KdfParams> for KdfParams {
fn from(value: super::KdfParams) -> Self {
Self {
algorithm: Ok(value.algorithm),
m_cost: Ok(value.m_cost),
p_cost: Ok(value.p_cost),
salt: Ok(value.salt),
t_cost: Ok(value.t_cost),
}
}
}
#[derive(Clone, Debug)]
pub struct Payload {
backup: ::std::result::Result<super::BackupEnvelope, ::std::string::String>,
confirm: ::std::result::Result<bool, ::std::string::String>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
password: ::std::result::Result<super::PayloadPassword, ::std::string::String>,
}
impl ::std::default::Default for Payload {
fn default() -> Self {
Self {
backup: Err("no value supplied for backup".to_string()),
confirm: Ok(Default::default()),
ext: Ok(Default::default()),
password: Err("no value supplied for password".to_string()),
}
}
}
impl Payload {
pub fn backup<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::BackupEnvelope>,
T::Error: ::std::fmt::Display,
{
self.backup = value
.try_into()
.map_err(|e| format!("error converting supplied value for backup: {e}"));
self
}
pub fn confirm<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<bool>,
T::Error: ::std::fmt::Display,
{
self.confirm = value
.try_into()
.map_err(|e| format!("error converting supplied value for confirm: {e}"));
self
}
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn password<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::PayloadPassword>,
T::Error: ::std::fmt::Display,
{
self.password = value
.try_into()
.map_err(|e| format!("error converting supplied value for password: {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 {
backup: value.backup?,
confirm: value.confirm?,
ext: value.ext?,
password: value.password?,
})
}
}
impl ::std::convert::From<super::Payload> for Payload {
fn from(value: super::Payload) -> Self {
Self {
backup: Ok(value.backup),
confirm: Ok(value.confirm),
ext: Ok(value.ext),
password: Ok(value.password),
}
}
}
#[derive(Clone, Debug)]
pub struct Response {
counts: ::std::result::Result<
::std::collections::HashMap<::std::string::String, u64>,
::std::string::String,
>,
ext: ::std::result::Result<::std::option::Option<super::Ext>, ::std::string::String>,
message: ::std::result::Result<super::ResponseMessage, ::std::string::String>,
source_did: ::std::result::Result<
::std::option::Option<::std::string::String>,
::std::string::String,
>,
status: ::std::result::Result<super::ResponseStatus, ::std::string::String>,
}
impl ::std::default::Default for Response {
fn default() -> Self {
Self {
counts: Err("no value supplied for counts".to_string()),
ext: Ok(Default::default()),
message: Err("no value supplied for message".to_string()),
source_did: Ok(Default::default()),
status: Err("no value supplied for status".to_string()),
}
}
}
impl Response {
pub fn counts<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::collections::HashMap<::std::string::String, u64>>,
T::Error: ::std::fmt::Display,
{
self.counts = value
.try_into()
.map_err(|e| format!("error converting supplied value for counts: {e}"));
self
}
pub fn ext<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<super::Ext>>,
T::Error: ::std::fmt::Display,
{
self.ext = value
.try_into()
.map_err(|e| format!("error converting supplied value for ext: {e}"));
self
}
pub fn message<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseMessage>,
T::Error: ::std::fmt::Display,
{
self.message = value
.try_into()
.map_err(|e| format!("error converting supplied value for message: {e}"));
self
}
pub fn source_did<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<::std::option::Option<::std::string::String>>,
T::Error: ::std::fmt::Display,
{
self.source_did = value
.try_into()
.map_err(|e| format!("error converting supplied value for source_did: {e}"));
self
}
pub fn status<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::ResponseStatus>,
T::Error: ::std::fmt::Display,
{
self.status = value
.try_into()
.map_err(|e| format!("error converting supplied value for status: {e}"));
self
}
}
impl ::std::convert::TryFrom<Response> for super::Response {
type Error = super::error::ConversionError;
fn try_from(value: Response) -> ::std::result::Result<Self, super::error::ConversionError> {
Ok(Self {
counts: value.counts?,
ext: value.ext?,
message: value.message?,
source_did: value.source_did?,
status: value.status?,
})
}
}
impl ::std::convert::From<super::Response> for Response {
fn from(value: super::Response) -> Self {
Self {
counts: Ok(value.counts),
ext: Ok(value.ext),
message: Ok(value.message),
source_did: Ok(value.source_did),
status: Ok(value.status),
}
}
}
}
impl crate::Payload for Payload {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vtc/backup/import/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 \"BackupEnvelope\": {\n \"$anchor\": \"backupEnvelope\",\n \"additionalProperties\": false,\n \"description\": \"Unencrypted metadata plus the encrypted payload. The KDF and cipher parameters travel in the clear so a reader can decrypt without knowing this specification's defaults.\",\n \"properties\": {\n \"ciphertext\": {\n \"description\": \"base64url(AEAD(JSON(payload))).\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"createdAt\": {\n \"description\": \"When the export was taken.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"encryption\": {\n \"$ref\": \"#/$defs/EncryptionParams\"\n },\n \"format\": {\n \"description\": \"Envelope format tag, e.g. `vtc-backup-v1`.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"includesAudit\": {\n \"description\": \"Whether the audit log and its signed checkpoints are inside `ciphertext`.\",\n \"type\": \"boolean\"\n },\n \"kdf\": {\n \"$ref\": \"#/$defs/KdfParams\"\n },\n \"sourceDid\": {\n \"description\": \"DID of the community exported from, when it has one. An import cross-checks this against the running community.\",\n \"type\": [\n \"string\",\n \"null\"\n ]\n },\n \"sourceVersion\": {\n \"description\": \"Version of the software that produced the envelope.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"version\": {\n \"description\": \"Envelope schema version.\",\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"version\",\n \"format\",\n \"createdAt\",\n \"sourceVersion\",\n \"kdf\",\n \"encryption\",\n \"includesAudit\",\n \"ciphertext\"\n ],\n \"title\": \"BackupEnvelope\",\n \"type\": \"object\"\n },\n \"EncryptionParams\": {\n \"$anchor\": \"encryptionParams\",\n \"additionalProperties\": false,\n \"properties\": {\n \"algorithm\": {\n \"description\": \"AEAD identifier, e.g. `aes-256-gcm`.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"nonce\": {\n \"description\": \"base64url, 12 bytes.\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"algorithm\",\n \"nonce\"\n ],\n \"title\": \"EncryptionParams\",\n \"type\": \"object\"\n },\n \"Ext\": {\n \"additionalProperties\": true,\n \"description\": \"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\n \"minProperties\": 1,\n \"propertyNames\": {\n \"pattern\": \"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"\n },\n \"title\": \"Ext\",\n \"type\": \"object\"\n },\n \"KdfParams\": {\n \"$anchor\": \"kdfParams\",\n \"additionalProperties\": false,\n \"properties\": {\n \"algorithm\": {\n \"description\": \"KDF identifier, e.g. `argon2id`.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"mCost\": {\n \"description\": \"Argon2id memory cost (KiB).\",\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"pCost\": {\n \"description\": \"Argon2id parallelism.\",\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"salt\": {\n \"description\": \"base64url, 32 bytes.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"tCost\": {\n \"description\": \"Argon2id time cost (iterations).\",\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"algorithm\",\n \"salt\",\n \"mCost\",\n \"tCost\",\n \"pCost\"\n ],\n \"title\": \"KdfParams\",\n \"type\": \"object\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"properties\": {\n \"counts\": {\n \"additionalProperties\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"description\": \"Per-keyspace row counts written, or that would be written on a preview.\",\n \"type\": \"object\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"message\": {\n \"description\": \"Human-readable summary for the operator.\",\n \"maxLength\": 1024,\n \"type\": \"string\"\n },\n \"sourceDid\": {\n \"description\": \"The community DID the envelope was taken from.\",\n \"type\": [\n \"string\",\n \"null\"\n ]\n },\n \"status\": {\n \"description\": \"`preview` when `confirm` was not set; `imported` after a restore.\",\n \"enum\": [\n \"preview\",\n \"imported\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"status\",\n \"counts\",\n \"message\"\n ],\n \"title\": \"VTC Backup Import — response payload\",\n \"type\": \"object\"\n }\n },\n \"$id\": \"https://trusttasks.org/spec/vtc/backup/import/0.1\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"additionalProperties\": false,\n \"properties\": {\n \"backup\": {\n \"$ref\": \"#/$defs/BackupEnvelope\",\n \"description\": \"The envelope returned by `vtc/backup/export`.\"\n },\n \"confirm\": {\n \"default\": false,\n \"description\": \"`false` (default) previews: row counts, no mutation. `true` clears the backed-up keyspaces and applies the backup.\",\n \"type\": \"boolean\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"password\": {\n \"description\": \"The passphrase the envelope was encrypted under.\",\n \"minLength\": 12,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"backup\",\n \"password\"\n ],\n \"title\": \"VTC Backup Import — payload\",\n \"type\": \"object\"\n}\n",
);
}
impl crate::Payload for Response {
const TYPE_URI: &'static str = "https://trusttasks.org/spec/vtc/backup/import/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 \"BackupEnvelope\": {\n \"$anchor\": \"backupEnvelope\",\n \"additionalProperties\": false,\n \"description\": \"Unencrypted metadata plus the encrypted payload. The KDF and cipher parameters travel in the clear so a reader can decrypt without knowing this specification's defaults.\",\n \"properties\": {\n \"ciphertext\": {\n \"description\": \"base64url(AEAD(JSON(payload))).\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"createdAt\": {\n \"description\": \"When the export was taken.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"encryption\": {\n \"$ref\": \"#/$defs/EncryptionParams\"\n },\n \"format\": {\n \"description\": \"Envelope format tag, e.g. `vtc-backup-v1`.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"includesAudit\": {\n \"description\": \"Whether the audit log and its signed checkpoints are inside `ciphertext`.\",\n \"type\": \"boolean\"\n },\n \"kdf\": {\n \"$ref\": \"#/$defs/KdfParams\"\n },\n \"sourceDid\": {\n \"description\": \"DID of the community exported from, when it has one. An import cross-checks this against the running community.\",\n \"type\": [\n \"string\",\n \"null\"\n ]\n },\n \"sourceVersion\": {\n \"description\": \"Version of the software that produced the envelope.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"version\": {\n \"description\": \"Envelope schema version.\",\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"version\",\n \"format\",\n \"createdAt\",\n \"sourceVersion\",\n \"kdf\",\n \"encryption\",\n \"includesAudit\",\n \"ciphertext\"\n ],\n \"title\": \"BackupEnvelope\",\n \"type\": \"object\"\n },\n \"EncryptionParams\": {\n \"$anchor\": \"encryptionParams\",\n \"additionalProperties\": false,\n \"properties\": {\n \"algorithm\": {\n \"description\": \"AEAD identifier, e.g. `aes-256-gcm`.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"nonce\": {\n \"description\": \"base64url, 12 bytes.\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"algorithm\",\n \"nonce\"\n ],\n \"title\": \"EncryptionParams\",\n \"type\": \"object\"\n },\n \"Ext\": {\n \"additionalProperties\": true,\n \"description\": \"Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.\",\n \"minProperties\": 1,\n \"propertyNames\": {\n \"pattern\": \"^[a-z][a-z0-9-]*(\\\\.[a-z0-9-]+)+$\"\n },\n \"title\": \"Ext\",\n \"type\": \"object\"\n },\n \"KdfParams\": {\n \"$anchor\": \"kdfParams\",\n \"additionalProperties\": false,\n \"properties\": {\n \"algorithm\": {\n \"description\": \"KDF identifier, e.g. `argon2id`.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"mCost\": {\n \"description\": \"Argon2id memory cost (KiB).\",\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"pCost\": {\n \"description\": \"Argon2id parallelism.\",\n \"minimum\": 1,\n \"type\": \"integer\"\n },\n \"salt\": {\n \"description\": \"base64url, 32 bytes.\",\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"tCost\": {\n \"description\": \"Argon2id time cost (iterations).\",\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"algorithm\",\n \"salt\",\n \"mCost\",\n \"tCost\",\n \"pCost\"\n ],\n \"title\": \"KdfParams\",\n \"type\": \"object\"\n },\n \"Response\": {\n \"$anchor\": \"response\",\n \"additionalProperties\": false,\n \"properties\": {\n \"counts\": {\n \"additionalProperties\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"description\": \"Per-keyspace row counts written, or that would be written on a preview.\",\n \"type\": \"object\"\n },\n \"ext\": {\n \"$ref\": \"#/$defs/Ext\"\n },\n \"message\": {\n \"description\": \"Human-readable summary for the operator.\",\n \"maxLength\": 1024,\n \"type\": \"string\"\n },\n \"sourceDid\": {\n \"description\": \"The community DID the envelope was taken from.\",\n \"type\": [\n \"string\",\n \"null\"\n ]\n },\n \"status\": {\n \"description\": \"`preview` when `confirm` was not set; `imported` after a restore.\",\n \"enum\": [\n \"preview\",\n \"imported\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"status\",\n \"counts\",\n \"message\"\n ],\n \"title\": \"VTC Backup Import — 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;
}
#[cfg(test)]
mod conformance {
//! Round-trip tests harvested from the spec's `spec.md`,
//! plus a `rejects_invalid_examples` test for any fixtures
//! in `payload.invalid-examples.json` (validate feature).
/// Each fixture in `payload.invalid-examples.json` MUST be
/// rejected by at least one of: serde deserialization, or
/// JSON-Schema validation under the `validate` feature. The
/// fixture file documents the producer-side bug class that
/// each payload exemplifies; this generated test pins it.
#[cfg(feature = "validate")]
#[test]
fn rejects_invalid_examples() {
use crate::validate::ValidatedPayload;
let fixtures: &[(&str, &str)] = &[
("`backup` and `password` are both required.", "{}"),
(
"`password` is required even when the envelope is present.",
"{\n \"backup\": {\n \"ciphertext\": \"Y3Q\",\n \"createdAt\": \"2026-07-26T10:00:00Z\",\n \"encryption\": {\n \"algorithm\": \"aes-256-gcm\",\n \"nonce\": \"bm9uY2U\"\n },\n \"format\": \"vtc-backup-v1\",\n \"includesAudit\": false,\n \"kdf\": {\n \"algorithm\": \"argon2id\",\n \"mCost\": 65536,\n \"pCost\": 4,\n \"salt\": \"c2FsdA\",\n \"tCost\": 3\n },\n \"sourceVersion\": \"0.11.28\",\n \"version\": 1\n }\n}",
),
(
"`status` is a closed enum; `restored` is not a member.",
"{\n \"backup\": {},\n \"password\": \"twelve-char-pw!!\",\n \"status\": \"restored\"\n}",
),
(
"Unknown top-level member is rejected.",
"{\n \"__x__\": true,\n \"backup\": {},\n \"password\": \"twelve-char-pw!!\"\n}",
),
];
for (i, (note, raw)) in fixtures.iter().enumerate() {
let value: serde_json::Value = match serde_json::from_str(raw) {
Ok(v) => v,
Err(_) => continue,
};
let serde_ok = serde_json::from_value::<super::Payload>(value.clone()).is_ok();
let schema_ok = super::Payload::validate_value(&value).is_ok();
assert!(
!(serde_ok && schema_ok),
"invalid-example #{} ({:?}) was accepted by both serde and JSON Schema; \
the fixture's stated failure class is no longer caught:\n{}",
i + 1,
note,
raw
);
}
}
}