camel-component-validator 0.14.0

Validator component for rust-camel (XSD, JSON Schema, YAML)
Documentation
use std::sync::Arc;

use thiserror::Error;

use crate::proto;

#[derive(Error, Debug, Clone)]
pub enum ValidatorError {
    #[error("{0}")]
    Endpoint(String),
    #[error("{0}")]
    Validation(String),
    #[error("{message}")]
    Transport {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },
    #[error("{0}")]
    UnsupportedMode(&'static str),
    #[error("{message}")]
    CompilationFailed {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },
    #[error("payload too large: {actual} bytes exceeds limit of {limit} bytes")]
    PayloadTooLarge { actual: usize, limit: usize },
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn transport_variant_preserves_source_chain() {
        let inner = std::io::Error::other("socket closed");
        let err = ValidatorError::transport_with_source("rpc failed", inner);
        let source = std::error::Error::source(&err);
        assert!(source.is_some());
        assert!(source.unwrap().to_string().contains("socket closed"));
    }
}

impl ValidatorError {
    pub fn endpoint(msg: impl Into<String>) -> Self {
        Self::Endpoint(msg.into())
    }

    pub fn validation(msg: impl Into<String>) -> Self {
        Self::Validation(msg.into())
    }

    pub fn transport_with_source(
        msg: impl Into<String>,
        source: impl std::error::Error + Send + Sync + 'static,
    ) -> Self {
        Self::Transport {
            message: msg.into(),
            source: Some(Arc::new(source)),
        }
    }

    pub fn from_bridge_error(err: &proto::BridgeError) -> Self {
        let msg = err.message.clone();
        match proto::bridge_error::Kind::try_from(err.kind)
            .unwrap_or(proto::bridge_error::Kind::Unknown)
        {
            proto::bridge_error::Kind::CompilationFailed => Self::CompilationFailed {
                message: msg,
                source: None,
            },
            proto::bridge_error::Kind::ValidationFailed => Self::Validation(msg),
            proto::bridge_error::Kind::Unknown
            | proto::bridge_error::Kind::InvalidInput
            | proto::bridge_error::Kind::TransformFailed
            | proto::bridge_error::Kind::ResourceNotFound
            | proto::bridge_error::Kind::SecurityViolation
            | proto::bridge_error::Kind::Internal => Self::Transport {
                message: msg,
                source: None,
            },
        }
    }

    pub fn to_endpoint_error(&self) -> camel_component_api::CamelError {
        camel_component_api::CamelError::EndpointCreationFailed(self.to_string())
    }

    pub fn to_processor_error(&self) -> camel_component_api::CamelError {
        camel_component_api::CamelError::ProcessorError(self.to_string())
    }
}