|
@@ -0,0 +1,71 @@
|
|
|
+/// This example demonstrates how to define custom error types and map SBI error codes.
|
|
|
+///
|
|
|
+/// The code shows:
|
|
|
+/// - How to create a custom error enum that wraps standard SBI errors and adds custom error codes
|
|
|
+/// - Conversion logic between standard SBI errors and custom error types
|
|
|
+/// - Error handling patterns using Rust's Result type and error matching
|
|
|
+use sbi_spec::binary::{Error, SbiRet};
|
|
|
+
|
|
|
+/// Custom error type for SBI-related operations
|
|
|
+///
|
|
|
+/// Contains three possible variants:
|
|
|
+/// - Standard: Wraps standard SBI errors from the sbi_spec crate
|
|
|
+/// - MyErrorCode1/MyErrorCode2: Custom error codes specific to this implementation
|
|
|
+pub enum MyError {
|
|
|
+ /// Wrapper for standard SBI errors defined in sbi_spec
|
|
|
+ Standard(sbi_spec::binary::Error),
|
|
|
+ /// First custom error code (maps to value 1001)
|
|
|
+ MyErrorCode1,
|
|
|
+ /// Second custom error code (maps to value 1002)
|
|
|
+ MyErrorCode2,
|
|
|
+}
|
|
|
+
|
|
|
+/// Numeric value for first custom error code
|
|
|
+const MY_ERROR_CODE_1: usize = 1001;
|
|
|
+/// Numeric value for second custom error code
|
|
|
+const MY_ERROR_CODE_2: usize = 1002;
|
|
|
+
|
|
|
+/// Conversion implementation from standard SBI errors to our custom error type
|
|
|
+///
|
|
|
+/// This allows automatic conversion when using the ? operator in functions returning MyError.
|
|
|
+/// The conversion logic:
|
|
|
+/// - Maps specific custom error codes to their corresponding MyError variants
|
|
|
+/// - Wraps all other standard errors in the Standard variant
|
|
|
+impl From<sbi_spec::binary::Error> for MyError {
|
|
|
+ fn from(value: Error) -> Self {
|
|
|
+ match value {
|
|
|
+ // Handle custom error code mappings
|
|
|
+ Error::Custom(MY_ERROR_CODE_1) => MyError::MyErrorCode1,
|
|
|
+ Error::Custom(MY_ERROR_CODE_2) => MyError::MyErrorCode2,
|
|
|
+ // Wrap all other standard errors
|
|
|
+ _ => MyError::Standard(value),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// Main function demonstrating error handling workflow
|
|
|
+///
|
|
|
+/// The execution flow:
|
|
|
+/// 1. Creates an SbiRet structure with success status
|
|
|
+/// 2. Manually sets an error code for demonstration
|
|
|
+/// 3. Converts the SbiRet to Result type with custom error mapping
|
|
|
+/// 4. Pattern matches on the result to handle different error cases
|
|
|
+fn main() {
|
|
|
+ // Create a base SbiRet with success status (value = 0)
|
|
|
+ let mut ret = SbiRet::success(0);
|
|
|
+ // Override the error code for demonstration purposes
|
|
|
+ ret.error = 1001;
|
|
|
+
|
|
|
+ // Convert SbiRet to Result, mapping error codes to MyError variants
|
|
|
+ let ans = ret.map_err(MyError::from);
|
|
|
+
|
|
|
+ // Handle different error cases through pattern matching
|
|
|
+ match ans {
|
|
|
+ Ok(_) => println!("Okay"),
|
|
|
+ // Match specific custom error codes
|
|
|
+ Err(MyError::MyErrorCode1) => println!("Custom error code 1"),
|
|
|
+ Err(MyError::MyErrorCode2) => println!("Custom error code 2"),
|
|
|
+ // Handle wrapped standard SBI errors
|
|
|
+ Err(MyError::Standard(err)) => println!("Standard error: {:?}", err),
|
|
|
+ }
|
|
|
+}
|