1# Using generic types 2 3Error types enhanced by SNAFU may contain generic type and lifetime parameters. 4 5## Types 6 7```rust 8# use snafu::{Snafu, ensure}; 9# 10#[derive(Debug, Snafu)] 11enum Error<T> 12where 13 T: std::fmt::Display, 14{ 15 #[snafu(display("The value {} was too large", value))] 16 TooLarge { value: T, limit: u32 }, 17 18 #[snafu(display("The value {} was too small", value))] 19 TooSmall { value: T, limit: u32 }, 20} 21 22fn validate_number(value: u8) -> Result<u8, Error<u8>> { 23 ensure!(value <= 200, TooLarge { value, limit: 100u32 }); 24 ensure!(value >= 100, TooSmall { value, limit: 200u32 }); 25 Ok(value) 26} 27 28fn validate_string(value: &str) -> Result<&str, Error<String>> { 29 ensure!(value.len() <= 20, TooLarge { value, limit: 10u32 }); 30 ensure!(value.len() >= 10, TooSmall { value, limit: 20u32 }); 31 Ok(value) 32} 33``` 34 35## Lifetimes 36 37```rust 38# use snafu::{Snafu, ensure}; 39# 40#[derive(Debug, Snafu)] 41enum Error<'a> { 42 #[snafu(display("The username {} contains the bad word {}", value, word))] 43 BadWord { value: &'a str, word: &'static str }, 44} 45 46fn validate_username<'a>(value: &'a str) -> Result<&'a str, Error<'a>> { 47 ensure!(!value.contains("stinks"), BadWord { value, word: "stinks" }); 48 ensure!(!value.contains("smells"), BadWord { value, word: "smells" }); 49 Ok(value) 50} 51``` 52 53## Caveats 54 55A SNAFU [opaque type](crate::guide::opaque) requires that the 56contained type implements several traits, such as 57`Display`. However, type constraints cannot be automatically added 58to the opaque type because they are not allowed to reference the 59inner type without also exposing it publicly. 60 61The best option is to avoid using a generic opaque error. If you 62choose to expose a generic opaque error, you will likely need to add 63explicit duplicate type constraints: 64 65```rust 66use snafu::Snafu; 67 68#[derive(Debug, Snafu)] 69struct ApiError<T>(Error<T>) 70where // These lines are required to 71 T: std::fmt::Debug; // ensure that delegation can work. 72 73#[derive(Debug, Snafu)] 74enum Error<T> 75where 76 T: std::fmt::Debug, 77{ 78 #[snafu(display("Boom: {:?}", value))] 79 Boom { value: T }, 80} 81``` 82