sql-fun 0.1.0

SQL query/statement execution code generator
Documentation
use proc_macro::TokenStream;

use crate::TokioPostgresCodeGeneratorBuilderError;

#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct SqlFunError(SqlFunErrorInner);

#[derive(Debug, thiserror::Error)]
pub enum SqlFunErrorInner {
    #[error("SQL parse error: {0}")]
    SqlParse(#[from] pg_query::Error),

    #[error("Syntax error: {0}")]
    Syntax(#[from] syn::Error),

    #[error("Metadata error: {0}")]
    Metadata(#[from] toml::de::Error),

    #[error("{0}")]
    Custom(String),

    #[error("Unnamed column found in result set.")]
    UnnamedColumnInResultSet,

    #[error("Code generator setup failed {0}")]
    GeneratorBuilder(#[from] TokioPostgresCodeGeneratorBuilderError),

    #[error("file IO error")]
    Io(#[from] std::io::Error),

    #[error(transparent)]
    Args(#[from] sql_fun_core::SqlFunArgsError),

    #[error(transparent)]
    ArgMetadata(#[from] sql_fun_core::MetadataError),
}

impl SqlFunErrorInner {
    pub fn to_compile_error(&self) -> TokenStream {
        match self {
            Self::GeneratorBuilder(err) => syn::Error::new_spanned(
                "",
                format!("unexpected code generator setup failed {err:?}"),
            )
            .into_compile_error()
            .into(),
            Self::SqlParse(err) => syn::Error::new_spanned("", format!("SQL parse error: {err:?}"))
                .into_compile_error()
                .into(),
            Self::Syntax(err) => err.clone().into_compile_error().into(),
            Self::Metadata(err) => syn::Error::new_spanned("", format!("Metadata error: {err:?}"))
                .into_compile_error()
                .into(),
            Self::Custom(err) => syn::Error::new_spanned("", err).into_compile_error().into(),
            Self::UnnamedColumnInResultSet => syn::Error::new_spanned(
                "",
                r#"Unnamed column found in result set.
Column expressions must have an alias.
Fix: Use `AS` to name computed columns."#,
            )
            .into_compile_error()
            .into(),
            Self::Io(e) => syn::Error::new_spanned("", format!("IO error {e:?}"))
                .into_compile_error()
                .into(),
            Self::Args(e) => syn::Error::new_spanned("", format!("Argument error {e:?}"))
                .into_compile_error()
                .into(),
            Self::ArgMetadata(e) => syn::Error::new_spanned("", format!("Metadata error {e:?}"))
                .into_compile_error()
                .into(),
        }
    }
}

impl SqlFunError {
    pub fn to_compile_error(&self) -> TokenStream {
        self.0.to_compile_error()
    }

    pub fn custom(message: &str) -> Self {
        Self(SqlFunErrorInner::Custom(message.to_string()))
    }

    pub fn unnamed_column_in_result_rowset() -> Self {
        Self(SqlFunErrorInner::UnnamedColumnInResultSet)
    }
}

impl From<pg_query::Error> for SqlFunError {
    fn from(err: pg_query::Error) -> Self {
        Self(SqlFunErrorInner::from(err))
    }
}

impl From<syn::Error> for SqlFunError {
    fn from(err: syn::Error) -> Self {
        Self(SqlFunErrorInner::from(err))
    }
}

impl From<TokioPostgresCodeGeneratorBuilderError> for SqlFunError {
    fn from(err: TokioPostgresCodeGeneratorBuilderError) -> Self {
        Self(SqlFunErrorInner::from(err))
    }
}

impl From<std::io::Error> for SqlFunError {
    fn from(err: std::io::Error) -> Self {
        Self(SqlFunErrorInner::from(err))
    }
}

impl From<sql_fun_core::SqlFunArgsError> for SqlFunError {
    fn from(err: sql_fun_core::SqlFunArgsError) -> Self {
        Self(SqlFunErrorInner::from(err))
    }
}

impl From<sql_fun_core::MetadataError> for SqlFunError {
    fn from(err: sql_fun_core::MetadataError) -> Self {
        Self(SqlFunErrorInner::from(err))
    }
}