error.rs (3088B)
1 /* -*- Mode: rust; rust-indent-offset: 4 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 use std::fmt; 7 8 /// Helper macro to create an Error that knows which file and line it occurred 9 /// on. Can optionally have some extra information as a String. 10 #[macro_export] 11 macro_rules! error_here { 12 ($error_type:expr) => { 13 Error::new($error_type, file!(), line!(), None) 14 }; 15 ($error_type:expr, $info:expr) => { 16 Error::new($error_type, file!(), line!(), Some($info)) 17 }; 18 } 19 20 /// Error type for identifying errors in this crate. Use the error_here! macro 21 /// to instantiate. 22 #[derive(Debug)] 23 pub struct Error { 24 typ: ErrorType, 25 file: &'static str, 26 line: u32, 27 info: Option<String>, 28 } 29 30 impl Error { 31 pub fn new(typ: ErrorType, file: &'static str, line: u32, info: Option<String>) -> Error { 32 Error { 33 typ, 34 file, 35 line, 36 info, 37 } 38 } 39 } 40 41 impl fmt::Display for Error { 42 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 43 if let Some(info) = &self.info { 44 write!(f, "{} at {}:{} ({})", self.typ, self.file, self.line, info) 45 } else { 46 write!(f, "{} at {}:{}", self.typ, self.file, self.line) 47 } 48 } 49 } 50 51 impl Clone for Error { 52 fn clone(&self) -> Self { 53 Error { 54 typ: self.typ, 55 file: self.file, 56 line: self.line, 57 info: self.info.as_ref().cloned(), 58 } 59 } 60 61 fn clone_from(&mut self, source: &Self) { 62 self.typ = source.typ; 63 self.file = source.file; 64 self.line = source.line; 65 self.info = source.info.as_ref().cloned(); 66 } 67 } 68 69 #[derive(Copy, Clone, Debug)] 70 pub enum ErrorType { 71 /// An error in an external library or resource. 72 ExternalError, 73 /// Unexpected extra input (e.g. in an ASN.1 encoding). 74 ExtraInput, 75 /// Invalid argument. 76 InvalidArgument, 77 /// Invalid data input. 78 InvalidInput, 79 /// An internal library failure (e.g. an expected invariant failed). 80 LibraryFailure, 81 /// Truncated input (e.g. in an ASN.1 encoding). 82 TruncatedInput, 83 /// Unsupported input. 84 UnsupportedInput, 85 /// A given value could not be represented in the type used for it. 86 ValueTooLarge, 87 } 88 89 impl fmt::Display for ErrorType { 90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 91 let error_type_str = match self { 92 ErrorType::ExternalError => "ExternalError", 93 ErrorType::ExtraInput => "ExtraInput", 94 ErrorType::InvalidArgument => "InvalidArgument", 95 ErrorType::InvalidInput => "InvalidInput", 96 ErrorType::LibraryFailure => "LibraryFailure", 97 ErrorType::TruncatedInput => "TruncatedInput", 98 ErrorType::UnsupportedInput => "UnsupportedInput", 99 ErrorType::ValueTooLarge => "ValueTooLarge", 100 }; 101 write!(f, "{}", error_type_str) 102 } 103 }