//! 宪法宏错误处理模块 - 完整实现 use std::fmt; /// 宏错误类型 #[derive(Debug, Clone)] pub enum MacroError { /// 缺少必需参数 MissingParameter { parameter: String, span_info: String, }, /// 无效的参数值 InvalidParameter { parameter: String, value: String, expected: String, }, /// 类型检查失败 TypeCheckFailed { expected_type: String, actual_type: String, location: String, }, /// 边界检查失败 BoundaryCheckFailed { value: String, min: Option, max: Option, }, /// 表达式解析失败 ExpressionParseFailed { expression: String, error: String, }, /// 代码生成失败 CodeGenerationFailed { reason: String, }, /// 元数据生成失败 MetadataGenerationFailed { reason: String, }, /// 未知错误 Unknown { message: String, }, } impl MacroError { /// 转换为编译错误 pub fn to_compile_error(&self) -> proc_macro2::TokenStream { let message = self.to_string(); quote::quote! { compile_error!(#message); } } /// 创建缺少参数错误 pub fn missing_parameter(parameter: impl Into, span_info: impl Into) -> Self { Self::MissingParameter { parameter: parameter.into(), span_info: span_info.into(), } } /// 创建无效参数错误 pub fn invalid_parameter( parameter: impl Into, value: impl Into, expected: impl Into, ) -> Self { Self::InvalidParameter { parameter: parameter.into(), value: value.into(), expected: expected.into(), } } /// 创建类型检查失败错误 pub fn type_check_failed( expected_type: impl Into, actual_type: impl Into, location: impl Into, ) -> Self { Self::TypeCheckFailed { expected_type: expected_type.into(), actual_type: actual_type.into(), location: location.into(), } } /// 创建边界检查失败错误 pub fn boundary_check_failed( value: impl Into, min: Option, max: Option, ) -> Self { Self::BoundaryCheckFailed { value: value.into(), min, max, } } /// 创建表达式解析失败错误 pub fn expression_parse_failed( expression: impl Into, error: impl Into, ) -> Self { Self::ExpressionParseFailed { expression: expression.into(), error: error.into(), } } /// 创建代码生成失败错误 pub fn code_generation_failed(reason: impl Into) -> Self { Self::CodeGenerationFailed { reason: reason.into(), } } /// 创建元数据生成失败错误 pub fn metadata_generation_failed(reason: impl Into) -> Self { Self::MetadataGenerationFailed { reason: reason.into(), } } /// 创建未知错误 pub fn unknown(message: impl Into) -> Self { Self::Unknown { message: message.into(), } } } impl fmt::Display for MacroError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::MissingParameter { parameter, span_info } => { write!( f, "Missing required parameter '{}' at {}", parameter, span_info ) } Self::InvalidParameter { parameter, value, expected, } => { write!( f, "Invalid value '{}' for parameter '{}', expected: {}", value, parameter, expected ) } Self::TypeCheckFailed { expected_type, actual_type, location, } => { write!( f, "Type check failed at {}: expected '{}', found '{}'", location, expected_type, actual_type ) } Self::BoundaryCheckFailed { value, min, max } => { let bounds = match (min, max) { (Some(min), Some(max)) => format!("between {} and {}", min, max), (Some(min), None) => format!(">= {}", min), (None, Some(max)) => format!("<= {}", max), (None, None) => "within valid range".to_string(), }; write!(f, "Boundary check failed: value '{}' must be {}", value, bounds) } Self::ExpressionParseFailed { expression, error } => { write!( f, "Failed to parse expression '{}': {}", expression, error ) } Self::CodeGenerationFailed { reason } => { write!(f, "Code generation failed: {}", reason) } Self::MetadataGenerationFailed { reason } => { write!(f, "Metadata generation failed: {}", reason) } Self::Unknown { message } => { write!(f, "Unknown error: {}", message) } } } } impl std::error::Error for MacroError {} impl From for MacroError { fn from(error: syn::Error) -> Self { Self::Unknown { message: error.to_string(), } } } impl From for syn::Error { fn from(error: MacroError) -> Self { syn::Error::new(proc_macro2::Span::call_site(), error.to_string()) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_missing_parameter_error() { let error = MacroError::missing_parameter("clause", "line 10"); assert!(error.to_string().contains("Missing required parameter 'clause'")); } #[test] fn test_invalid_parameter_error() { let error = MacroError::invalid_parameter("check", "invalid", "boolean expression"); assert!(error.to_string().contains("Invalid value 'invalid'")); } #[test] fn test_type_check_failed_error() { let error = MacroError::type_check_failed("u64", "String", "parameter 'amount'"); assert!(error.to_string().contains("Type check failed")); } #[test] fn test_boundary_check_failed_error() { let error = MacroError::boundary_check_failed("150", Some("0".to_string()), Some("100".to_string())); assert!(error.to_string().contains("Boundary check failed")); } }