use derive_more::From;
use orion_error::{DomainReason, ErrorCode, StructError, UvsReason};
use serde_derive::Serialize;
use thiserror::Error;
#[derive(Debug, PartialEq, Serialize, Error, From)]
pub enum OrionSecReason {
#[error("{0}")]
Sec(SecReason),
#[error("{0}")]
Uvs(UvsReason),
}
impl DomainReason for OrionSecReason {}
#[derive(Debug, PartialEq, Serialize, Error)]
pub enum SecReason {
#[error("sensitive msg {0}")]
SensitiveMsg(String),
#[error("no permission {0}")]
NoPermission(String),
#[error("deception {0}")]
Deception(String),
#[error("un authenticated {0}")]
UnAuthenticated(String),
}
pub type SecError = StructError<OrionSecReason>;
pub type SecResult<T> = Result<T, SecError>;
impl ErrorCode for OrionSecReason {
fn error_code(&self) -> i32 {
match self {
OrionSecReason::Sec(sec_reason) => match sec_reason {
SecReason::SensitiveMsg(_) => 101,
SecReason::NoPermission(_) => 201,
SecReason::Deception(_) => 301,
SecReason::UnAuthenticated(_) => 401,
},
OrionSecReason::Uvs(u) => u.error_code(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use orion_conf::ToStructError;
use orion_error::ErrorConv;
use orion_error::compat_traits::ErrorOwe;
#[derive(Debug, PartialEq, Serialize, Error, From)]
pub enum TargetReason {
#[error("{0}")]
Uvs(UvsReason),
}
impl DomainReason for TargetReason {}
pub type TargetError = StructError<TargetReason>;
impl From<OrionSecReason> for TargetReason {
fn from(value: OrionSecReason) -> Self {
match value {
OrionSecReason::Sec(_) => Self::Uvs(UvsReason::permission_error()),
OrionSecReason::Uvs(u) => Self::Uvs(u),
}
}
}
fn err_fun() -> SecResult<()> {
OrionSecReason::Sec(SecReason::NoPermission("no perm".to_string())).err_result()
}
fn call_err() -> Result<(), TargetError> {
err_fun().err_conv()
}
#[test]
fn test_err_conv() {
match call_err() {
Ok(_) => todo!(),
Err(e) => {
println!("{:#?}", e);
}
}
}
#[test]
fn test_sec_reason_sensitive_msg() {
let reason = SecReason::SensitiveMsg("test message".to_string());
assert_eq!(format!("{}", reason), "sensitive msg test message");
}
#[test]
fn test_sec_error_creation() {
let reason = OrionSecReason::Sec(SecReason::SensitiveMsg("operation failed".to_string()));
let error: SecError = Result::<(), OrionSecReason>::Err(reason)
.owe_logic()
.unwrap_err();
let debug_str = format!("{:?}", error);
assert!(debug_str.contains("operation failed"));
}
#[test]
fn test_sec_result_ok() {
fn successful_operation() -> SecResult<i32> {
Ok(42)
}
let result = successful_operation();
assert!(result.is_ok());
assert_eq!(result.unwrap(), 42);
}
#[test]
fn test_sec_result_err() {
fn failing_operation() -> SecResult<i32> {
let reason = OrionSecReason::Sec(SecReason::SensitiveMsg("not found".to_string()));
Result::<i32, OrionSecReason>::Err(reason).owe_logic()
}
let result = failing_operation();
assert!(result.is_err());
}
#[test]
fn test_orion_sec_reason_equality() {
let reason1 = OrionSecReason::Sec(SecReason::SensitiveMsg("a".to_string()));
let reason2 = OrionSecReason::Sec(SecReason::SensitiveMsg("a".to_string()));
let reason3 = OrionSecReason::Sec(SecReason::SensitiveMsg("b".to_string()));
assert_eq!(reason1, reason2);
assert_ne!(reason1, reason3);
}
#[test]
fn test_sec_reason_serializable() {
let reason = SecReason::SensitiveMsg("serialize me".to_string());
let serialized = serde_yaml::to_string(&reason);
assert!(serialized.is_ok());
assert!(serialized.unwrap().contains("serialize me"));
}
#[test]
fn test_orion_sec_reason_serializable() {
let reason = OrionSecReason::Sec(SecReason::SensitiveMsg("data".to_string()));
let debug_str = format!("{:?}", reason);
assert!(debug_str.contains("data"));
}
#[test]
fn test_sec_error_display() {
let reason = OrionSecReason::Sec(SecReason::SensitiveMsg("password leaked".to_string()));
let error: SecError = reason.to_err();
let display_str = format!("{}", error);
println!("{}", display_str);
assert!(display_str.contains("password leaked"));
assert_eq!(error.error_code(), 101);
}
}