nextest_runner/user_config/
experimental.rs1use serde::Deserialize;
11use std::{collections::BTreeSet, env, fmt, str::FromStr};
12
13#[derive(Clone, Copy, Debug, Default, Deserialize)]
22#[serde(rename_all = "kebab-case")]
23pub struct ExperimentalConfig {
24 #[serde(default)]
26 pub record: bool,
27}
28
29impl ExperimentalConfig {
30 pub fn to_set(self) -> BTreeSet<UserConfigExperimental> {
32 let Self { record } = self;
33 let mut set = BTreeSet::new();
34 if record {
35 set.insert(UserConfigExperimental::Record);
36 }
37 set
38 }
39}
40
41#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
47#[non_exhaustive]
48pub enum UserConfigExperimental {
49 Record,
51}
52
53impl UserConfigExperimental {
54 pub fn env_var(&self) -> &'static str {
56 match self {
57 Self::Record => "NEXTEST_EXPERIMENTAL_RECORD",
58 }
59 }
60
61 pub fn name(&self) -> &'static str {
63 match self {
64 Self::Record => "record",
65 }
66 }
67
68 pub fn all() -> &'static [Self] {
70 &[Self::Record]
71 }
72
73 pub fn from_env() -> BTreeSet<Self> {
77 Self::all()
78 .iter()
79 .filter(|feature| env::var(feature.env_var()).is_ok_and(|v| v == "1"))
80 .copied()
81 .collect()
82 }
83}
84
85impl fmt::Display for UserConfigExperimental {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.write_str(self.name())
88 }
89}
90
91impl FromStr for UserConfigExperimental {
92 type Err = UnknownUserExperimentalError;
93
94 fn from_str(s: &str) -> Result<Self, Self::Err> {
95 match s {
96 "record" => Ok(Self::Record),
97 _ => Err(UnknownUserExperimentalError {
98 feature: s.to_owned(),
99 }),
100 }
101 }
102}
103
104#[derive(Clone, Debug, Eq, PartialEq)]
106pub struct UnknownUserExperimentalError {
107 pub feature: String,
109}
110
111impl fmt::Display for UnknownUserExperimentalError {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(
114 f,
115 "unknown experimental feature `{}`; known features: {}",
116 self.feature,
117 UserConfigExperimental::all()
118 .iter()
119 .map(|f| f.name())
120 .collect::<Vec<_>>()
121 .join(", ")
122 )
123 }
124}
125
126impl std::error::Error for UnknownUserExperimentalError {}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_from_str() {
134 assert_eq!(
135 "record".parse::<UserConfigExperimental>().unwrap(),
136 UserConfigExperimental::Record
137 );
138
139 assert!("unknown".parse::<UserConfigExperimental>().is_err());
140 }
141
142 #[test]
143 fn test_display() {
144 assert_eq!(UserConfigExperimental::Record.to_string(), "record");
145 }
146
147 #[test]
148 fn test_env_var() {
149 assert_eq!(
150 UserConfigExperimental::Record.env_var(),
151 "NEXTEST_EXPERIMENTAL_RECORD"
152 );
153 }
154}