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