#![cfg(feature = "derive")]
use derive_more::From;
use orion_error::reason::{ErrorCategory, ErrorCode, ErrorIdentityProvider};
use orion_error::{
ErrorCode as ErrorCodeDerive, ErrorIdentityProvider as ErrorIdentityProviderDerive, OrionError,
UnifiedReason,
};
#[derive(Debug, Clone, PartialEq, From, OrionError)]
enum DerivedReason {
#[orion_error(identity = "biz.invalid_request")]
InvalidRequest,
#[orion_error(identity = "logic.internal_invariant_broken")]
InvariantBroken,
#[orion_error(
message = "storage temporarily unavailable",
code = 2000,
identity = "sys.storage_unavailable",
category = Sys
)]
StorageUnavailable,
#[orion_error(transparent)]
General(UnifiedReason),
}
#[derive(Debug, Clone, PartialEq, OrionError)]
#[orion_error(
message = "single struct reason",
code = 3000,
identity = "conf.single_struct"
)]
struct SingleStructReason;
#[derive(Debug, Clone, PartialEq, OrionError)]
#[orion_error(transparent)]
struct TransparentStructReason(UnifiedReason);
#[test]
fn derive_error_identity_for_enum_variants() {
let invalid = DerivedReason::InvalidRequest;
assert_eq!(invalid.error_code(), 500);
assert_eq!(invalid.stable_code(), "biz.invalid_request");
assert_eq!(invalid.error_category(), ErrorCategory::Biz);
let storage = DerivedReason::StorageUnavailable;
assert_eq!(storage.error_code(), 2000);
assert_eq!(storage.stable_code(), "sys.storage_unavailable");
assert_eq!(storage.error_category(), ErrorCategory::Sys);
}
#[test]
fn derive_error_identity_delegates_transparent_variant() {
let reason = DerivedReason::from(UnifiedReason::system_error());
assert_eq!(reason.error_code(), 201);
assert_eq!(reason.stable_code(), "sys.io_error");
assert_eq!(reason.error_category(), ErrorCategory::Sys);
}
#[test]
fn derive_error_identity_for_structs() {
let single = SingleStructReason;
assert_eq!(single.error_code(), 3000);
assert_eq!(single.stable_code(), "conf.single_struct");
assert_eq!(single.error_category(), ErrorCategory::Conf);
let transparent = TransparentStructReason(UnifiedReason::timeout_error());
assert_eq!(transparent.error_code(), 204);
assert_eq!(transparent.stable_code(), "sys.timeout");
assert_eq!(transparent.error_category(), ErrorCategory::Sys);
}
mod prelude_import {
use orion_error::prelude::*;
use orion_error::reason::{ErrorCategory, ErrorCode, ErrorIdentityProvider};
#[derive(Debug, Clone, PartialEq, OrionError)]
enum PreludeReason {
#[orion_error(identity = "logic.prelude_reason")]
Reason,
}
#[test]
fn prelude_import_exposes_derive_macro() {
let reason = PreludeReason::Reason;
assert_eq!(reason.error_code(), 500);
assert_eq!(reason.stable_code(), "logic.prelude_reason");
assert_eq!(reason.error_category(), ErrorCategory::Logic);
}
}
#[derive(Debug, Clone, PartialEq, ErrorCodeDerive)]
enum CodeOnlyReason {
#[orion_error(code = 4100)]
CodeOnly,
}
#[derive(Debug, Clone, PartialEq, ErrorIdentityProviderDerive)]
enum IdentityOnlyReason {
#[orion_error(identity = "logic.identity_only", category = "logic")]
IdentityOnly,
}
#[test]
fn individual_derives_remain_available() {
assert_eq!(CodeOnlyReason::CodeOnly.error_code(), 4100);
let reason = IdentityOnlyReason::IdentityOnly;
assert_eq!(reason.stable_code(), "logic.identity_only");
assert_eq!(reason.error_category(), ErrorCategory::Logic);
}
#[test]
fn orion_error_derive_implements_display() {
assert_eq!(DerivedReason::InvalidRequest.to_string(), "invalid request");
assert_eq!(
DerivedReason::InvariantBroken.to_string(),
"internal invariant broken"
);
assert_eq!(
DerivedReason::StorageUnavailable.to_string(),
"storage temporarily unavailable"
);
assert_eq!(
DerivedReason::from(UnifiedReason::timeout_error()).to_string(),
"timeout error"
);
assert_eq!(SingleStructReason.to_string(), "single struct reason");
assert_eq!(
TransparentStructReason(UnifiedReason::logic_error()).to_string(),
"BUG :logic error"
);
}
#[test]
fn test_uvs_reason_constructors_are_generated() {
let _ = DerivedReason::system_error();
let _ = DerivedReason::validation_error();
let _ = DerivedReason::not_found_error();
let _ = DerivedReason::core_conf();
}