nu_experimental/options/
mod.rs

1#![allow(
2    private_interfaces,
3    reason = "The marker structs don't need to be exposed, only the static values."
4)]
5
6use crate::*;
7
8mod example;
9mod reorder_cell_paths;
10
11/// Marker trait for defining experimental options.
12///
13/// Implement this trait to mark a struct as metadata for an [`ExperimentalOption`].
14/// It provides all necessary information about an experimental feature directly in code,
15/// without needing external documentation.
16///
17/// The `STATUS` field is especially important as it controls whether the feature is enabled
18/// by default and how users should interpret its reliability.
19pub(crate) trait ExperimentalOptionMarker {
20    /// Unique identifier for this experimental option.
21    ///
22    /// Must be a valid Rust identifier.
23    /// Used when parsing to toggle specific experimental options,
24    /// and may also serve as a user-facing label.
25    const IDENTIFIER: &'static str;
26
27    /// Brief description explaining what this option changes.
28    ///
29    /// Displayed to users in help messages or summaries without needing to visit external docs.
30    const DESCRIPTION: &'static str;
31
32    /// Indicates the status of an experimental status.
33    ///
34    /// Options marked [`Status::OptIn`] are disabled by default while options marked with
35    /// [`Status::OptOut`] are enabled by default.
36    /// Experimental options that stabilize should be marked as [`Status::DeprecatedDefault`] while
37    /// options that will be removed should be [`Status::DeprecatedDiscard`].
38    const STATUS: Status;
39}
40
41// Export only the static values.
42// The marker structs are not relevant and needlessly clutter the generated docs.
43pub use example::EXAMPLE;
44pub use reorder_cell_paths::REORDER_CELL_PATHS;
45
46// Include all experimental option statics in here.
47// This will test them and add them to the parsing list.
48
49/// A list of all available experimental options.
50///
51/// Use this to show users every experimental option, including their descriptions,
52/// identifiers, and current state.
53pub static ALL: &[&ExperimentalOption] = &[&EXAMPLE, &REORDER_CELL_PATHS];
54
55#[cfg(test)]
56mod tests {
57    use std::collections::HashSet;
58
59    use super::*;
60
61    #[test]
62    fn assert_identifiers_are_unique() {
63        let list: Vec<_> = ALL.iter().map(|opt| opt.identifier()).collect();
64        let set: HashSet<_> = HashSet::from_iter(&list);
65        assert_eq!(list.len(), set.len());
66    }
67
68    #[test]
69    fn assert_identifiers_are_valid() {
70        for option in ALL {
71            let identifier = option.identifier();
72            assert!(!identifier.is_empty());
73
74            let mut chars = identifier.chars();
75            let first = chars.next().expect("not empty");
76            assert!(first.is_alphabetic());
77            assert!(first.is_lowercase());
78
79            for char in chars {
80                assert!(char.is_alphanumeric() || char == '-');
81                if char.is_alphabetic() {
82                    assert!(char.is_lowercase());
83                }
84            }
85        }
86    }
87
88    #[test]
89    fn assert_description_not_empty() {
90        for option in ALL {
91            assert!(!option.description().is_empty());
92        }
93    }
94}