1use std::fmt::{Display, Formatter};
4
5use indexmap::IndexMap;
6use serde_json::Value;
7
8use crate::Env;
9
10#[derive(Clone)]
11pub enum RustFlags {
12 Lint(String, Lint),
13 Combine(Box<RustFlags>, Box<RustFlags>),
14}
15#[derive(Clone)]
16pub enum Lint {
17 Allow,
18 Warn,
19 Deny,
20 Forbid,
21 Codegen,
22 Experiment,
23}
24
25impl core::ops::Add for RustFlags {
26 type Output = RustFlags;
27
28 fn add(self, rhs: Self) -> Self::Output {
29 RustFlags::Combine(Box::new(self), Box::new(rhs))
30 }
31}
32
33impl RustFlags {
34 pub fn allow<S: ToString>(name: S) -> Self {
35 RustFlags::Lint(name.to_string(), Lint::Allow)
36 }
37
38 pub fn warn<S: ToString>(name: S) -> Self {
39 RustFlags::Lint(name.to_string(), Lint::Warn)
40 }
41
42 pub fn deny<S: ToString>(name: S) -> Self {
43 RustFlags::Lint(name.to_string(), Lint::Deny)
44 }
45
46 pub fn forbid<S: ToString>(name: S) -> Self {
47 RustFlags::Lint(name.to_string(), Lint::Forbid)
48 }
49
50 pub fn codegen<S: ToString>(name: S) -> Self {
51 RustFlags::Lint(name.to_string(), Lint::Codegen)
52 }
53}
54
55impl Display for RustFlags {
56 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57 match self {
58 RustFlags::Lint(name, lint) => match lint {
59 Lint::Allow => write!(f, "-A{name}"),
60 Lint::Warn => write!(f, "-W{name}"),
61 Lint::Deny => write!(f, "-D{name}"),
62 Lint::Forbid => write!(f, "-F{name}"),
63 Lint::Codegen => write!(f, "-C{name}"),
64 Lint::Experiment => write!(f, "-Z{name}"),
65 },
66 RustFlags::Combine(lhs, rhs) => write!(f, "{lhs} {rhs}"),
67 }
68 }
69}
70
71impl From<RustFlags> for Env {
72 fn from(value: RustFlags) -> Self {
73 let mut env = IndexMap::default();
74 env.insert("RUSTFLAGS".to_string(), Value::from(value.to_string()));
75 Env::from(env)
76 }
77}