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