From e3cefad7bd204a30ccb9a4aa35fed5eb868e218e Mon Sep 17 00:00:00 2001 From: RA <70325462+RAprogramm@users.noreply.github.com> Date: Sat, 27 Sep 2025 09:05:12 +0700 Subject: [PATCH] Avoid cloning AppCode in response conversions --- src/response/mapping.rs | 4 ++-- src/response/problem_json.rs | 2 +- tests/app_code_reuse.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 tests/app_code_reuse.rs diff --git a/src/response/mapping.rs b/src/response/mapping.rs index c43616d..631e842 100644 --- a/src/response/mapping.rs +++ b/src/response/mapping.rs @@ -2,7 +2,7 @@ use alloc::string::String; use core::fmt::{Display, Formatter, Result as FmtResult}; use super::core::ErrorResponse; -use crate::AppError; +use crate::{AppCode, AppError}; impl Display for ErrorResponse { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { @@ -14,7 +14,7 @@ impl Display for ErrorResponse { impl From for ErrorResponse { fn from(mut err: AppError) -> Self { let kind = err.kind; - let code = err.code.clone(); + let code = core::mem::replace(&mut err.code, AppCode::from(kind)); let retry = err.retry.take(); let www_authenticate = err.www_authenticate.take(); let policy = err.edit_policy; diff --git a/src/response/problem_json.rs b/src/response/problem_json.rs index 8c9e1f1..21e2003 100644 --- a/src/response/problem_json.rs +++ b/src/response/problem_json.rs @@ -162,8 +162,8 @@ impl ProblemJson { pub fn from_app_error(mut error: AppError) -> Self { error.emit_telemetry(); - let code = error.code.clone(); let kind = error.kind; + let code = core::mem::replace(&mut error.code, AppCode::from(kind)); let message = error.message.take(); let metadata = core::mem::take(&mut error.metadata); let edit_policy = error.edit_policy; diff --git a/tests/app_code_reuse.rs b/tests/app_code_reuse.rs new file mode 100644 index 0000000..46e4e4f --- /dev/null +++ b/tests/app_code_reuse.rs @@ -0,0 +1,27 @@ +use masterror::{AppCode, AppError, ErrorResponse, ProblemJson}; + +fn error_with_dynamic_code() -> AppError { + let code = AppCode::try_new("DYNAMIC_REGRESSION_CODE".to_owned()) + .expect("valid SCREAMING_SNAKE_CASE code"); + AppError::internal("boom").with_code(code) +} + +#[test] +fn problem_json_reuses_app_code_allocation() { + let error = error_with_dynamic_code(); + let expected_ptr = error.code.as_str().as_ptr(); + + let problem = ProblemJson::from_app_error(error); + + assert_eq!(problem.code.as_str().as_ptr(), expected_ptr); +} + +#[test] +fn error_response_reuses_app_code_allocation() { + let error = error_with_dynamic_code(); + let expected_ptr = error.code.as_str().as_ptr(); + + let response = ErrorResponse::from(error); + + assert_eq!(response.code.as_str().as_ptr(), expected_ptr); +}