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| {
80 env::var(feature.env_var())
81 .map(|v| v == "1")
82 .unwrap_or(false)
83 })
84 .copied()
85 .collect()
86 }
87}
88
89impl fmt::Display for UserConfigExperimental {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 f.write_str(self.name())
92 }
93}
94
95impl FromStr for UserConfigExperimental {
96 type Err = UnknownUserExperimentalError;
97
98 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 match s {
100 "record" => Ok(Self::Record),
101 _ => Err(UnknownUserExperimentalError {
102 feature: s.to_owned(),
103 }),
104 }
105 }
106}
107
108#[derive(Clone, Debug, Eq, PartialEq)]
110pub struct UnknownUserExperimentalError {
111 pub feature: String,
113}
114
115impl fmt::Display for UnknownUserExperimentalError {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 write!(
118 f,
119 "unknown experimental feature `{}`; known features: {}",
120 self.feature,
121 UserConfigExperimental::all()
122 .iter()
123 .map(|f| f.name())
124 .collect::<Vec<_>>()
125 .join(", ")
126 )
127 }
128}
129
130impl std::error::Error for UnknownUserExperimentalError {}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn test_from_str() {
138 assert_eq!(
139 "record".parse::<UserConfigExperimental>().unwrap(),
140 UserConfigExperimental::Record
141 );
142
143 assert!("unknown".parse::<UserConfigExperimental>().is_err());
144 }
145
146 #[test]
147 fn test_display() {
148 assert_eq!(UserConfigExperimental::Record.to_string(), "record");
149 }
150
151 #[test]
152 fn test_env_var() {
153 assert_eq!(
154 UserConfigExperimental::Record.env_var(),
155 "NEXTEST_EXPERIMENTAL_RECORD"
156 );
157 }
158}