4
0

custom-sbi-error.rs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /// This example demonstrates how to define custom error types and map SBI error codes.
  2. ///
  3. /// The code shows:
  4. /// - How to create a custom error enum that wraps standard SBI errors and adds custom error codes
  5. /// - Conversion logic between standard SBI errors and custom error types
  6. /// - Error handling patterns using Rust's Result type and error matching
  7. use sbi_spec::binary::{Error, SbiRet};
  8. /// Custom error type for SBI-related operations
  9. ///
  10. /// Contains three possible variants:
  11. /// - Standard: Wraps standard SBI errors from the sbi_spec crate
  12. /// - MyErrorCode1/MyErrorCode2: Custom error codes specific to this implementation
  13. pub enum MyError {
  14. /// Wrapper for standard SBI errors defined in sbi_spec
  15. Standard(sbi_spec::binary::Error),
  16. /// First custom error code (maps to value 1001)
  17. MyErrorCode1,
  18. /// Second custom error code (maps to value 1002)
  19. MyErrorCode2,
  20. }
  21. /// Numeric value for first custom error code
  22. const MY_ERROR_CODE_1: usize = 1001;
  23. /// Numeric value for second custom error code
  24. const MY_ERROR_CODE_2: usize = 1002;
  25. /// Conversion implementation from standard SBI errors to our custom error type
  26. ///
  27. /// This allows automatic conversion when using the ? operator in functions returning MyError.
  28. /// The conversion logic:
  29. /// - Maps specific custom error codes to their corresponding MyError variants
  30. /// - Wraps all other standard errors in the Standard variant
  31. impl From<sbi_spec::binary::Error> for MyError {
  32. fn from(value: Error) -> Self {
  33. match value {
  34. // Handle custom error code mappings
  35. Error::Custom(MY_ERROR_CODE_1) => MyError::MyErrorCode1,
  36. Error::Custom(MY_ERROR_CODE_2) => MyError::MyErrorCode2,
  37. // Wrap all other standard errors
  38. _ => MyError::Standard(value),
  39. }
  40. }
  41. }
  42. /// Main function demonstrating error handling workflow
  43. ///
  44. /// The execution flow:
  45. /// 1. Creates an SbiRet structure with success status
  46. /// 2. Manually sets an error code for demonstration
  47. /// 3. Converts the SbiRet to Result type with custom error mapping
  48. /// 4. Pattern matches on the result to handle different error cases
  49. fn main() {
  50. // Create a base SbiRet with success status (value = 0)
  51. let mut ret = SbiRet::success(0);
  52. // Override the error code for demonstration purposes
  53. ret.error = 1001;
  54. // Convert SbiRet to Result, mapping error codes to MyError variants
  55. let ans = ret.map_err(MyError::from);
  56. // Handle different error cases through pattern matching
  57. match ans {
  58. Ok(_) => println!("Okay"),
  59. // Match specific custom error codes
  60. Err(MyError::MyErrorCode1) => println!("Custom error code 1"),
  61. Err(MyError::MyErrorCode2) => println!("Custom error code 2"),
  62. // Handle wrapped standard SBI errors
  63. Err(MyError::Standard(err)) => println!("Standard error: {:?}", err),
  64. }
  65. }