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 cell_path_types;
9mod enforce_runtime_annotations;
10mod example;
11mod native_clip;
12mod pipefail;
13mod reorder_cell_paths;
14
15pub(crate) type Version = (u16, u16, u16);
16
17/// Marker trait for defining experimental options.
18///
19/// Implement this trait to mark a struct as metadata for an [`ExperimentalOption`].
20/// It provides all necessary information about an experimental feature directly in code,
21/// without needing external documentation.
22///
23/// The `STATUS` field is especially important as it controls whether the feature is enabled
24/// by default and how users should interpret its reliability.
25pub(crate) trait ExperimentalOptionMarker {
26 /// Unique identifier for this experimental option.
27 ///
28 /// Must be a valid Rust identifier.
29 /// Used when parsing to toggle specific experimental options,
30 /// and may also serve as a user-facing label.
31 const IDENTIFIER: &'static str;
32
33 /// Brief description explaining what this option changes.
34 ///
35 /// Displayed to users in help messages or summaries without needing to visit external docs.
36 const DESCRIPTION: &'static str;
37
38 /// Indicates the status of an experimental status.
39 ///
40 /// Options marked [`Status::OptIn`] are disabled by default while options marked with
41 /// [`Status::OptOut`] are enabled by default.
42 /// Experimental options that stabilize should be marked as [`Status::DeprecatedDefault`] while
43 /// options that will be removed should be [`Status::DeprecatedDiscard`].
44 const STATUS: Status;
45
46 /// Nushell version since this experimental option is available.
47 ///
48 /// These three values represent major.minor.patch version.
49 /// Don't use some macro to generate this dynamically as this would defeat the purpose of having
50 /// a historic record.
51 const SINCE: Version;
52
53 /// Github issue that tracks this experimental option.
54 ///
55 /// Experimental options are expected to end their lifetime by either getting a default feature
56 /// or by getting removed.
57 /// To track this we want to have a respective issue on Github that tracks the status.
58 const ISSUE: u32;
59}
60
61// Export only the static values.
62// The marker structs are not relevant and needlessly clutter the generated docs.
63pub use cell_path_types::CELL_PATH_TYPES;
64pub use enforce_runtime_annotations::ENFORCE_RUNTIME_ANNOTATIONS;
65pub use example::EXAMPLE;
66pub use native_clip::NATIVE_CLIP;
67pub use pipefail::PIPE_FAIL;
68pub use reorder_cell_paths::REORDER_CELL_PATHS;
69
70// Include all experimental option statics in here.
71// This will test them and add them to the parsing list.
72
73/// A list of all available experimental options.
74///
75/// Use this to show users every experimental option, including their descriptions,
76/// identifiers, and current state.
77pub static ALL: &[&ExperimentalOption] = &[
78 &EXAMPLE,
79 &REORDER_CELL_PATHS,
80 &PIPE_FAIL,
81 &ENFORCE_RUNTIME_ANNOTATIONS,
82 &NATIVE_CLIP,
83 &CELL_PATH_TYPES,
84];
85
86#[cfg(test)]
87mod tests {
88 use std::collections::HashSet;
89
90 use super::*;
91
92 #[test]
93 fn assert_identifiers_are_unique() {
94 let list: Vec<_> = ALL.iter().map(|opt| opt.identifier()).collect();
95 let set: HashSet<_> = HashSet::from_iter(&list);
96 assert_eq!(list.len(), set.len());
97 }
98
99 #[test]
100 fn assert_identifiers_are_valid() {
101 for option in ALL {
102 let identifier = option.identifier();
103 assert!(!identifier.is_empty());
104
105 let mut chars = identifier.chars();
106 let first = chars.next().expect("not empty");
107 assert!(first.is_alphabetic());
108 assert!(first.is_lowercase());
109
110 for char in chars {
111 assert!(char.is_alphanumeric() || char == '-');
112 if char.is_alphabetic() {
113 assert!(char.is_lowercase());
114 }
115 }
116 }
117 }
118
119 #[test]
120 fn assert_description_not_empty() {
121 for option in ALL {
122 assert!(!option.description().is_empty());
123 }
124 }
125}