1 #![deny(clippy::all, clippy::pedantic)] 2 #![allow(clippy::option_if_let_else)] 3 4 use std::fmt::Display; 5 use thiserror::Error; 6 7 // Some of the elaborate cases from the rcc codebase, which is a C compiler in 8 // Rust. https://github.com/jyn514/rcc/blob/0.8.0/src/data/error.rs 9 #[derive(Error, Debug)] 10 pub enum CompilerError { 11 #[error("cannot shift {} by {maximum} or more bits (got {current})", if *.is_left { "left" } else { "right" })] 12 TooManyShiftBits { 13 is_left: bool, 14 maximum: u64, 15 current: u64, 16 }, 17 18 #[error("#error {}", (.0).iter().copied().collect::<Vec<_>>().join(" "))] 19 User(Vec<&'static str>), 20 21 #[error("overflow while parsing {}integer literal", 22 if let Some(signed) = .is_signed { 23 if *signed { "signed "} else { "unsigned "} 24 } else { 25 "" 26 } 27 )] 28 IntegerOverflow { is_signed: Option<bool> }, 29 30 #[error("overflow while parsing {}integer literal", match .is_signed { 31 Some(true) => "signed ", 32 Some(false) => "unsigned ", 33 None => "", 34 })] 35 IntegerOverflow2 { is_signed: Option<bool> }, 36 } 37 38 // Examples drawn from Rustup. 39 #[derive(Error, Debug)] 40 pub enum RustupError { 41 #[error( 42 "toolchain '{name}' does not contain component {component}{}", 43 .suggestion 44 .as_ref() 45 .map_or_else(String::new, |s| format!("; did you mean '{}'?", s)), 46 )] 47 UnknownComponent { 48 name: String, 49 component: String, 50 suggestion: Option<String>, 51 }, 52 } 53 54 fn assert<T: Display>(expected: &str, value: T) { 55 assert_eq!(expected, value.to_string()); 56 } 57 58 #[test] 59 fn test_rcc() { 60 assert( 61 "cannot shift left by 32 or more bits (got 50)", 62 CompilerError::TooManyShiftBits { 63 is_left: true, 64 maximum: 32, 65 current: 50, 66 }, 67 ); 68 69 assert("#error A B C", CompilerError::User(vec!["A", "B", "C"])); 70 71 assert( 72 "overflow while parsing signed integer literal", 73 CompilerError::IntegerOverflow { 74 is_signed: Some(true), 75 }, 76 ); 77 } 78 79 #[test] 80 fn test_rustup() { 81 assert( 82 "toolchain 'nightly' does not contain component clipy; did you mean 'clippy'?", 83 RustupError::UnknownComponent { 84 name: "nightly".to_owned(), 85 component: "clipy".to_owned(), 86 suggestion: Some("clippy".to_owned()), 87 }, 88 ); 89 } 90