#![warn(clippy::all, missing_docs)]
extern crate self as conjure_error;
use conjure_object::Uuid;
use serde::{Serialize, Serializer};
use crate::ser::{ParametersSerializer, StringSeed};
pub use crate::error::*;
pub use crate::types::*;
use serde::de::DeserializeSeed;
mod error;
mod ser;
#[allow(clippy::all, missing_docs)]
#[rustfmt::skip]
mod types;
impl ErrorCode {
#[inline]
pub fn status_code(&self) -> u16 {
match self {
ErrorCode::PermissionDenied => 403,
ErrorCode::InvalidArgument => 400,
ErrorCode::NotFound => 404,
ErrorCode::Conflict => 409,
ErrorCode::RequestEntityTooLarge => 413,
ErrorCode::FailedPrecondition => 500,
ErrorCode::Internal => 500,
ErrorCode::Timeout => 500,
ErrorCode::CustomClient => 400,
ErrorCode::CustomServer => 500,
}
}
}
pub trait ErrorType {
fn code(&self) -> ErrorCode;
fn name(&self) -> &str;
fn instance_id(&self) -> Option<Uuid>;
fn safe_args(&self) -> &'static [&'static str];
#[inline]
fn with_instance_id(self, instance_id: Uuid) -> WithInstanceId<Self>
where
Self: Sized,
{
WithInstanceId {
error: self,
instance_id,
}
}
}
impl<T> ErrorType for &T
where
T: ?Sized + ErrorType,
{
#[inline]
fn code(&self) -> ErrorCode {
(**self).code()
}
#[inline]
fn name(&self) -> &str {
(**self).name()
}
#[inline]
fn instance_id(&self) -> Option<Uuid> {
(**self).instance_id()
}
#[inline]
fn safe_args(&self) -> &'static [&'static str] {
(**self).safe_args()
}
}
pub struct WithInstanceId<T> {
error: T,
instance_id: Uuid,
}
impl<T> ErrorType for WithInstanceId<T>
where
T: ErrorType,
{
fn code(&self) -> ErrorCode {
self.error.code()
}
fn name(&self) -> &str {
self.error.name()
}
fn instance_id(&self) -> Option<Uuid> {
Some(self.instance_id)
}
fn safe_args(&self) -> &'static [&'static str] {
self.error.safe_args()
}
}
impl<T> Serialize for WithInstanceId<T>
where
T: Serialize,
{
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.error.serialize(s)
}
}
pub fn encode<T>(error: &T) -> SerializableError
where
T: ErrorType + Serialize,
{
let mut builder = SerializableError::builder();
let parameters = error
.serialize(ParametersSerializer)
.expect("failed to serialize error parameters");
for (key, value) in parameters {
if let Ok(value) = StringSeed.deserialize(value) {
builder.insert_parameters(key, value);
}
}
builder
.error_code(error.code())
.error_name(error.name())
.error_instance_id(error.instance_id().unwrap_or_else(Uuid::new_v4))
.build()
}