1#![doc = include_str!("../README.md")]
2use log::trace;
3use nu_parser::parse;
4use nu_protocol::{
5 VirtualPathId,
6 engine::{FileStack, StateWorkingSet, VirtualPath},
7 report_parse_error,
8};
9use std::path::PathBuf;
10
11fn create_virt_file(working_set: &mut StateWorkingSet, name: &str, content: &str) -> VirtualPathId {
12 let sanitized_name = PathBuf::from(name).to_string_lossy().to_string();
13 let file_id = working_set.add_file(sanitized_name.clone(), content.as_bytes());
14
15 working_set.add_virtual_path(sanitized_name, VirtualPath::File(file_id))
16}
17
18pub fn load_standard_library(
19 engine_state: &mut nu_protocol::engine::EngineState,
20) -> Result<(), miette::ErrReport> {
21 trace!("load_standard_library");
22
23 let mut working_set = StateWorkingSet::new(engine_state);
24
25 let mut std_virt_paths = vec![];
27
28 let std_mod_virt_file_id = create_virt_file(
30 &mut working_set,
31 "std/mod.nu",
32 include_str!("../std/mod.nu"),
33 );
34 std_virt_paths.push(std_mod_virt_file_id);
35
36 let mut std_submodules = vec![
38 (
40 "mod.nu",
41 "std/prelude",
42 include_str!("../std/prelude/mod.nu"),
43 ),
44 ("mod.nu", "std/assert", include_str!("../std/assert/mod.nu")),
46 ("mod.nu", "std/bench", include_str!("../std/bench/mod.nu")),
47 ("mod.nu", "std/dirs", include_str!("../std/dirs/mod.nu")),
48 ("mod.nu", "std/dt", include_str!("../std/dt/mod.nu")),
49 (
50 "mod.nu",
51 "std/formats",
52 include_str!("../std/formats/mod.nu"),
53 ),
54 ("mod.nu", "std/help", include_str!("../std/help/mod.nu")),
55 ("mod.nu", "std/input", include_str!("../std/input/mod.nu")),
56 ("mod.nu", "std/iter", include_str!("../std/iter/mod.nu")),
57 ("mod.nu", "std/log", include_str!("../std/log/mod.nu")),
58 ("mod.nu", "std/math", include_str!("../std/math/mod.nu")),
59 ("mod.nu", "std/util", include_str!("../std/util/mod.nu")),
60 ("mod.nu", "std/xml", include_str!("../std/xml/mod.nu")),
61 ("mod.nu", "std/config", include_str!("../std/config/mod.nu")),
62 (
63 "mod.nu",
64 "std/testing",
65 include_str!("../std/testing/mod.nu"),
66 ),
67 ("mod.nu", "std/clip", include_str!("../std/clip/mod.nu")),
68 ("mod.nu", "std/random", include_str!("../std/random/mod.nu")),
69 ];
70
71 for (filename, std_subdir_name, content) in std_submodules.drain(..) {
72 let mod_dir = PathBuf::from(std_subdir_name);
73 let name = mod_dir.join(filename);
74 let virt_file_id = create_virt_file(&mut working_set, &name.to_string_lossy(), content);
75
76 let mod_dir_filelist = vec![virt_file_id];
78
79 let virt_dir_id = working_set.add_virtual_path(
80 mod_dir.to_string_lossy().to_string(),
81 VirtualPath::Dir(mod_dir_filelist),
82 );
83 std_virt_paths.push(virt_dir_id);
85 }
86
87 let std_dir = PathBuf::from("std").to_string_lossy().to_string();
89 let _ = working_set.add_virtual_path(std_dir, VirtualPath::Dir(std_virt_paths));
90
91 let mut std_rfc_virt_paths = vec![];
93
94 let std_rfc_mod_virt_file_id = create_virt_file(
96 &mut working_set,
97 "std-rfc/mod.nu",
98 include_str!("../std-rfc/mod.nu"),
99 );
100 std_rfc_virt_paths.push(std_rfc_mod_virt_file_id);
101
102 let mut std_rfc_submodules = vec![
104 (
105 "mod.nu",
106 "std-rfc/clip",
107 include_str!("../std-rfc/clip/mod.nu"),
108 ),
109 (
110 "mod.nu",
111 "std-rfc/conversions",
112 include_str!("../std-rfc/conversions/mod.nu"),
113 ),
114 #[cfg(feature = "sqlite")]
115 ("mod.nu", "std-rfc/kv", include_str!("../std-rfc/kv/mod.nu")),
116 (
117 "mod.nu",
118 "std-rfc/path",
119 include_str!("../std-rfc/path/mod.nu"),
120 ),
121 (
122 "mod.nu",
123 "std-rfc/str",
124 include_str!("../std-rfc/str/mod.nu"),
125 ),
126 (
127 "mod.nu",
128 "std-rfc/tables",
129 include_str!("../std-rfc/tables/mod.nu"),
130 ),
131 (
132 "mod.nu",
133 "std-rfc/iter",
134 include_str!("../std-rfc/iter/mod.nu"),
135 ),
136 (
137 "mod.nu",
138 "std-rfc/random",
139 include_str!("../std-rfc/random/mod.nu"),
140 ),
141 ];
142
143 for (filename, std_rfc_subdir_name, content) in std_rfc_submodules.drain(..) {
144 let mod_dir = PathBuf::from(std_rfc_subdir_name);
145 let name = mod_dir.join(filename);
146 let virt_file_id = create_virt_file(&mut working_set, &name.to_string_lossy(), content);
147
148 let mod_dir_filelist = vec![virt_file_id];
150
151 let virt_dir_id = working_set.add_virtual_path(
152 mod_dir.to_string_lossy().to_string(),
153 VirtualPath::Dir(mod_dir_filelist),
154 );
155 std_rfc_virt_paths.push(virt_dir_id);
157 }
158
159 let std_rfc_dir = PathBuf::from("std-rfc").to_string_lossy().to_string();
161 let _ = working_set.add_virtual_path(std_rfc_dir, VirtualPath::Dir(std_rfc_virt_paths));
162
163 let (_, delta) = {
165 let source = r#"
166# Prelude
167use std/prelude *
168"#;
169
170 let placeholder = PathBuf::from("load std/prelude");
173 working_set.files = FileStack::with_file(placeholder);
174
175 let block = parse(
176 &mut working_set,
177 Some("loading stdlib prelude"),
178 source.as_bytes(),
179 false,
180 );
181
182 working_set.files.pop();
184
185 if let Some(err) = working_set.parse_errors.first() {
186 report_parse_error(&working_set, err);
187 }
188
189 (block, working_set.render())
190 };
191
192 engine_state.merge_delta(delta)?;
193
194 Ok(())
195}