foundry_config/
lint.rs
1use clap::ValueEnum;
4use core::fmt;
5use serde::{Deserialize, Deserializer, Serialize};
6use solar_interface::diagnostics::Level;
7use std::str::FromStr;
8use yansi::Paint;
9
10#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
12pub struct LinterConfig {
13 pub severity: Vec<Severity>,
17
18 pub exclude_lints: Vec<String>,
20
21 pub ignore: Vec<String>,
23
24 pub lint_on_build: bool,
28
29 pub mixed_case_exceptions: Vec<String>,
33}
34
35impl Default for LinterConfig {
36 fn default() -> Self {
37 Self {
38 lint_on_build: true,
39 severity: Vec::new(),
40 exclude_lints: Vec::new(),
41 ignore: Vec::new(),
42 mixed_case_exceptions: vec!["ERC".to_string()],
43 }
44 }
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Serialize)]
49pub enum Severity {
50 High,
51 Med,
52 Low,
53 Info,
54 Gas,
55 CodeSize,
56}
57
58impl Severity {
59 pub fn color(&self, message: &str) -> String {
60 match self {
61 Self::High => Paint::red(message).bold().to_string(),
62 Self::Med => Paint::rgb(message, 255, 135, 61).bold().to_string(),
63 Self::Low => Paint::yellow(message).bold().to_string(),
64 Self::Info => Paint::cyan(message).bold().to_string(),
65 Self::Gas => Paint::green(message).bold().to_string(),
66 Self::CodeSize => Paint::green(message).bold().to_string(),
67 }
68 }
69}
70
71impl From<Severity> for Level {
72 fn from(severity: Severity) -> Self {
73 match severity {
74 Severity::High | Severity::Med | Severity::Low => Self::Warning,
75 Severity::Info | Severity::Gas | Severity::CodeSize => Self::Note,
76 }
77 }
78}
79
80impl fmt::Display for Severity {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 let colored = match self {
83 Self::High => self.color("High"),
84 Self::Med => self.color("Med"),
85 Self::Low => self.color("Low"),
86 Self::Info => self.color("Info"),
87 Self::Gas => self.color("Gas"),
88 Self::CodeSize => self.color("CodeSize"),
89 };
90 write!(f, "{colored}")
91 }
92}
93
94impl<'de> Deserialize<'de> for Severity {
96 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
97 where
98 D: Deserializer<'de>,
99 {
100 let s = String::deserialize(deserializer)?;
101 FromStr::from_str(&s).map_err(serde::de::Error::custom)
102 }
103}
104
105impl FromStr for Severity {
106 type Err = String;
107
108 fn from_str(s: &str) -> Result<Self, Self::Err> {
109 match s.to_lowercase().as_str() {
110 "high" => Ok(Self::High),
111 "med" | "medium" => Ok(Self::Med),
112 "low" => Ok(Self::Low),
113 "info" => Ok(Self::Info),
114 "gas" => Ok(Self::Gas),
115 "size" | "codesize" | "code-size" => Ok(Self::CodeSize),
116 _ => Err(format!(
117 "unknown variant: found `{s}`, expected `one of `High`, `Med`, `Low`, `Info`, `Gas`, `CodeSize`"
118 )),
119 }
120 }
121}