esylla-core 0.1.0

Core esylla contract: the Module trait, app builder, and migration runner.
//! `#[derive(EsyllaError)]` works on downstream error enums (explicit mappings
//! and `transparent` forwarding). Uses local enums, not any framework-owned type.

use axum::http::StatusCode;
use esylla_core::EsyllaError; // the trait
use esylla_macros::EsyllaError; // the derive (macro namespace; coexists with the trait)

#[derive(Debug, thiserror::Error, EsyllaError)]
enum DemoError {
    #[esylla(status = NOT_FOUND, code = "demo.not_found")]
    #[error("not found")]
    NotFound,
    #[esylla(status = BAD_REQUEST, code = "demo.bad_input")]
    #[error("bad input: {0}")]
    BadInput(String),
}

#[test]
fn maps_explicit_variants() {
    assert_eq!(DemoError::NotFound.status(), StatusCode::NOT_FOUND);
    assert_eq!(DemoError::NotFound.code(), "demo.not_found");
    assert!(DemoError::NotFound.details().is_none());
    assert_eq!(
        DemoError::BadInput("x".into()).status(),
        StatusCode::BAD_REQUEST
    );
    assert_eq!(DemoError::BadInput("x".into()).code(), "demo.bad_input");
}

#[derive(Debug, thiserror::Error, EsyllaError)]
enum Wrapper {
    #[esylla(transparent)]
    #[error(transparent)]
    Demo(#[from] DemoError),
}

#[test]
fn transparent_forwards_to_inner() {
    let w = Wrapper::from(DemoError::NotFound);
    assert_eq!(w.status(), StatusCode::NOT_FOUND);
    assert_eq!(w.code(), "demo.not_found");
}