nu_protocol/config/
history.rs1use super::{config_update_string_enum, prelude::*};
2use crate::{self as nu_protocol, ConfigWarning};
3
4#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
5pub enum HistoryFileFormat {
6 #[cfg(feature = "sqlite")]
8 Sqlite,
9 Plaintext,
11}
12
13impl HistoryFileFormat {
14 pub fn default_file_name(self) -> std::path::PathBuf {
15 match self {
16 HistoryFileFormat::Plaintext => "history.txt",
17 #[cfg(feature = "sqlite")]
18 HistoryFileFormat::Sqlite => "history.sqlite3",
19 }
20 .into()
21 }
22}
23
24impl FromStr for HistoryFileFormat {
25 type Err = &'static str;
26
27 fn from_str(s: &str) -> Result<Self, Self::Err> {
28 match s.to_ascii_lowercase().as_str() {
29 #[cfg(feature = "sqlite")]
30 "sqlite" => Ok(Self::Sqlite),
31 "plaintext" => Ok(Self::Plaintext),
32 #[cfg(feature = "sqlite")]
33 _ => Err("'sqlite' or 'plaintext'"),
34 #[cfg(not(feature = "sqlite"))]
35 _ => Err("'plaintext'"),
36 }
37 }
38}
39
40impl UpdateFromValue for HistoryFileFormat {
41 fn update(&mut self, value: &Value, path: &mut ConfigPath, errors: &mut ConfigErrors) {
42 config_update_string_enum(self, value, path, errors)
43 }
44}
45
46#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
47pub struct HistoryConfig {
48 pub max_size: i64,
49 pub sync_on_enter: bool,
50 pub file_format: HistoryFileFormat,
51 pub isolation: bool,
52}
53
54impl HistoryConfig {
55 pub fn file_path(&self) -> Option<std::path::PathBuf> {
56 nu_path::nu_config_dir().map(|mut history_path| {
57 history_path.push(self.file_format.default_file_name());
58 history_path.into()
59 })
60 }
61}
62
63impl Default for HistoryConfig {
64 fn default() -> Self {
65 Self {
66 max_size: 100_000,
67 sync_on_enter: true,
68 file_format: HistoryFileFormat::Plaintext,
69 isolation: false,
70 }
71 }
72}
73
74impl UpdateFromValue for HistoryConfig {
75 fn update<'a>(
76 &mut self,
77 value: &'a Value,
78 path: &mut ConfigPath<'a>,
79 errors: &mut ConfigErrors,
80 ) {
81 let Value::Record { val: record, .. } = value else {
82 errors.type_mismatch(path, Type::record(), value);
83 return;
84 };
85
86 let mut isolation_span = value.span();
89
90 for (col, val) in record.iter() {
91 let path = &mut path.push(col);
92 match col.as_str() {
93 "isolation" => {
94 isolation_span = val.span();
95 self.isolation.update(val, path, errors)
96 }
97 "sync_on_enter" => self.sync_on_enter.update(val, path, errors),
98 "max_size" => self.max_size.update(val, path, errors),
99 "file_format" => self.file_format.update(val, path, errors),
100 _ => errors.unknown_option(path, val),
101 }
102 }
103
104 match (self.isolation, self.file_format) {
106 (true, HistoryFileFormat::Plaintext) => {
107 errors.warn(ConfigWarning::IncompatibleOptions {
108 label: "history isolation only compatible with SQLite format",
109 span: isolation_span,
110 help: r#"disable history isolation, or set $env.config.history.file_format = "sqlite""#,
111 });
112 }
113 #[cfg(feature = "sqlite")]
114 (true, HistoryFileFormat::Sqlite) => (),
115 (false, _) => (),
116 }
117 }
118}