#![doc = "Generated transport-independent contract objects."]
use std::collections::BTreeMap;
use std::error::Error as StdError;
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Deserializer, Serialize};
use spiral_contract::error::{ErrorEnvelope, ServiceError};
use spiral_contract::strict::{DeserializeStrict, Strict};
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct LegacyTables(pub BTreeMap<String, String>);
impl<'de> DeserializeStrict<'de> for LegacyTables {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self(
Strict::<BTreeMap<String, String>>::deserialize(deserializer)?.0,
))
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Parameters(pub String);
impl std::fmt::Display for Parameters {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(formatter)
}
}
impl<'de> DeserializeStrict<'de> for Parameters {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self(Strict::<String>::deserialize(deserializer)?.0))
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Query {
#[serde(rename = "defaultProjectId")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_project_id: Option<String>,
#[serde(rename = "defaultRef")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_ref: Option<String>,
#[serde(rename = "legacyTables")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub legacy_tables: Option<LegacyTables>,
#[serde(rename = "parameters")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parameters: Option<Parameters>,
#[serde(rename = "sql")]
pub sql: String,
}
impl<'de> DeserializeStrict<'de> for Query {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "defaultProjectId")]
#[serde(default)]
default_project_id: Strict<Option<String>>,
#[serde(rename = "defaultRef")]
#[serde(default)]
default_ref: Strict<Option<String>>,
#[serde(rename = "legacyTables")]
#[serde(default)]
legacy_tables: Strict<Option<LegacyTables>>,
#[serde(rename = "parameters")]
#[serde(default)]
parameters: Strict<Option<Parameters>>,
#[serde(rename = "sql")]
sql: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
default_project_id: wire.default_project_id.0,
default_ref: wire.default_ref.0,
legacy_tables: wire.legacy_tables.0,
parameters: wire.parameters.0,
sql: wire.sql.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SqlError {
Internal { message: String },
InvalidArgument { message: String },
NotFound { resource: String },
PermissionDenied { resource: String },
RequestTooLarge { message: String },
Timeout { message: String },
Unauthenticated { message: String },
Unavailable { message: String },
}
impl SqlError {
pub fn status(&self) -> u16 {
match self {
Self::Internal { .. } => 500,
Self::InvalidArgument { .. } => 400,
Self::NotFound { .. } => 404,
Self::PermissionDenied { .. } => 403,
Self::RequestTooLarge { .. } => 413,
Self::Timeout { .. } => 504,
Self::Unauthenticated { .. } => 401,
Self::Unavailable { .. } => 503,
}
}
pub fn envelope(&self, instance: String) -> ErrorEnvelope {
match self {
Self::Internal { message } => {
let mut envelope = ErrorEnvelope::new("INTERNAL", "Sql:Internal", instance);
envelope
.parameters
.insert("message".into(), message.to_string());
envelope
}
Self::InvalidArgument { message } => {
let mut envelope =
ErrorEnvelope::new("INVALID_ARGUMENT", "Sql:InvalidArgument", instance);
envelope
.parameters
.insert("message".into(), message.to_string());
envelope
}
Self::NotFound { resource } => {
let mut envelope = ErrorEnvelope::new("NOT_FOUND", "Sql:NotFound", instance);
envelope
.parameters
.insert("resource".into(), resource.to_string());
envelope
}
Self::PermissionDenied { resource } => {
let mut envelope =
ErrorEnvelope::new("PERMISSION_DENIED", "Sql:PermissionDenied", instance);
envelope
.parameters
.insert("resource".into(), resource.to_string());
envelope
}
Self::RequestTooLarge { message } => {
let mut envelope =
ErrorEnvelope::new("REQUEST_ENTITY_TOO_LARGE", "Sql:RequestTooLarge", instance);
envelope
.parameters
.insert("message".into(), message.to_string());
envelope
}
Self::Timeout { message } => {
let mut envelope = ErrorEnvelope::new("TIMEOUT", "Sql:Timeout", instance);
envelope
.parameters
.insert("message".into(), message.to_string());
envelope
}
Self::Unauthenticated { message } => {
let mut envelope =
ErrorEnvelope::new("UNAUTHENTICATED", "Sql:Unauthenticated", instance);
envelope
.parameters
.insert("message".into(), message.to_string());
envelope
}
Self::Unavailable { message } => {
let mut envelope = ErrorEnvelope::new("UNAVAILABLE", "Sql:Unavailable", instance);
envelope
.parameters
.insert("message".into(), message.to_string());
envelope
}
}
}
pub fn decode_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
if envelope.error_instance_id.len() != 36
|| Uuid::parse_str(&envelope.error_instance_id).is_err()
{
return None;
}
match envelope.error_name.as_str() {
"Sql:Internal" => {
if envelope.error_code != "INTERNAL" {
return None;
}
let message = envelope.parameters.get("message")?.clone();
Some(Self::Internal { message })
}
"Sql:InvalidArgument" => {
if envelope.error_code != "INVALID_ARGUMENT" {
return None;
}
let message = envelope.parameters.get("message")?.clone();
Some(Self::InvalidArgument { message })
}
"Sql:NotFound" => {
if envelope.error_code != "NOT_FOUND" {
return None;
}
let resource = envelope.parameters.get("resource")?.clone();
Some(Self::NotFound { resource })
}
"Sql:PermissionDenied" => {
if envelope.error_code != "PERMISSION_DENIED" {
return None;
}
let resource = envelope.parameters.get("resource")?.clone();
Some(Self::PermissionDenied { resource })
}
"Sql:RequestTooLarge" => {
if envelope.error_code != "REQUEST_ENTITY_TOO_LARGE" {
return None;
}
let message = envelope.parameters.get("message")?.clone();
Some(Self::RequestTooLarge { message })
}
"Sql:Timeout" => {
if envelope.error_code != "TIMEOUT" {
return None;
}
let message = envelope.parameters.get("message")?.clone();
Some(Self::Timeout { message })
}
"Sql:Unauthenticated" => {
if envelope.error_code != "UNAUTHENTICATED" {
return None;
}
let message = envelope.parameters.get("message")?.clone();
Some(Self::Unauthenticated { message })
}
"Sql:Unavailable" => {
if envelope.error_code != "UNAVAILABLE" {
return None;
}
let message = envelope.parameters.get("message")?.clone();
Some(Self::Unavailable { message })
}
_ => None,
}
}
}
impl Display for SqlError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Internal { message } => write!(formatter, "Sql:Internal (message: {})", message),
Self::InvalidArgument { message } => {
write!(formatter, "Sql:InvalidArgument (message: {})", message)
}
Self::NotFound { resource } => {
write!(formatter, "Sql:NotFound (resource: {})", resource)
}
Self::PermissionDenied { resource } => {
write!(formatter, "Sql:PermissionDenied (resource: {})", resource)
}
Self::RequestTooLarge { message } => {
write!(formatter, "Sql:RequestTooLarge (message: {})", message)
}
Self::Timeout { message } => write!(formatter, "Sql:Timeout (message: {})", message),
Self::Unauthenticated { message } => {
write!(formatter, "Sql:Unauthenticated (message: {})", message)
}
Self::Unavailable { message } => {
write!(formatter, "Sql:Unavailable (message: {})", message)
}
}
}
}
impl StdError for SqlError {}
impl ServiceError for SqlError {
fn to_envelope(&self, instance: String) -> ErrorEnvelope {
Self::envelope(self, instance)
}
fn from_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
Self::decode_envelope(envelope)
}
}