+61
-22
src/lib.rs
+61
-22
src/lib.rs
···
5
use nu_engine::{command_prelude::*, eval_block};
6
use nu_parser::{FlatShape, TokenContents, flatten_block, lex, parse};
7
use nu_protocol::{
8
-
Config, PipelineData, Span,
9
engine::{Call, EngineState, Stack, StateWorkingSet},
10
};
11
use serde::Serialize;
12
use std::{
13
sync::{Arc, Mutex, OnceLock},
14
time::UNIX_EPOCH,
15
};
···
146
);
147
148
let mut working_set = StateWorkingSet::new(engine_state);
149
-
150
-
// Capture the start offset *before* adding the file, as this is the global offset
151
-
// where our file begins.
152
let start_offset = working_set.next_span_start();
153
let block = parse(&mut working_set, Some("entry"), input.as_bytes(), false);
154
···
180
PipelineData::Empty,
181
);
182
183
-
let pipeline_data = result.map_err(cmd_err)?;
184
-
let table_command = nu_command::Table;
185
let call = Call::new(pipeline_data.span().unwrap_or_else(Span::unknown));
186
187
let res = table_command
188
-
.run(engine_state, stack, &call, pipeline_data.body)
189
.map_err(cmd_err)?;
190
191
match res {
···
195
}
196
PipelineData::ByteStream(s, _) => {
197
for line in s.lines().into_iter().flatten() {
198
-
let out = line.map_err(|e| CommandError {
199
-
error: Report::new(e),
200
-
start_offset,
201
-
})?;
202
print_to_console(&out, true);
203
}
204
}
···
224
STACK.get().unwrap().lock().expect("stack initialized"),
225
);
226
227
-
let result = std::panic::catch_unwind(move || {
228
-
match run_command_internal(&mut engine_guard, &mut stack_guard, input) {
229
-
Ok(_) => None,
230
-
Err(cmd_err) => Some(format_error(
231
-
cmd_err.error,
232
-
input.to_owned(),
233
-
cmd_err.start_offset,
234
-
)),
235
-
}
236
-
});
237
-
result.unwrap_or_else(|err| Some(format!("panicked: {err:?}")))
238
}
239
240
#[wasm_bindgen]
···
5
use nu_engine::{command_prelude::*, eval_block};
6
use nu_parser::{FlatShape, TokenContents, flatten_block, lex, parse};
7
use nu_protocol::{
8
+
Config, ListStream, PipelineData, Span,
9
engine::{Call, EngineState, Stack, StateWorkingSet},
10
};
11
use serde::Serialize;
12
use std::{
13
+
io::Cursor,
14
sync::{Arc, Mutex, OnceLock},
15
time::UNIX_EPOCH,
16
};
···
147
);
148
149
let mut working_set = StateWorkingSet::new(engine_state);
150
let start_offset = working_set.next_span_start();
151
let block = parse(&mut working_set, Some("entry"), input.as_bytes(), false);
152
···
178
PipelineData::Empty,
179
);
180
181
+
let pipeline_data = result.map_err(cmd_err)?.body;
182
+
let signals = engine_state.signals().clone();
183
+
184
+
// this is annoying but we have to collect here so we can uncover errors
185
+
// before passing the data off to Table, because otherwise Table
186
+
// can't properly handle the errors and panics (something about ShellErrorBridge
187
+
// having a non IO error in it somehow idk i dont care really)
188
+
// TODO: see if there is a way to do this without collecting the pipeline
189
+
let pipeline_data = match pipeline_data {
190
+
PipelineData::Empty => return Ok(()),
191
+
PipelineData::Value(Value::Error { error, .. }, _) => {
192
+
return Err(cmd_err(*error));
193
+
}
194
+
PipelineData::ByteStream(s, m) => match (s.span(), s.type_(), s.reader()) {
195
+
(span, ty, Some(r)) => {
196
+
use std::io::Read;
197
+
let v = r
198
+
.bytes()
199
+
.collect::<Result<Vec<u8>, _>>()
200
+
.map_err(|e| cmd_err(ShellError::Io(IoError::new(e, span, None))))?;
201
+
(v.len() > 0)
202
+
.then(|| {
203
+
PipelineData::byte_stream(
204
+
ByteStream::read(Cursor::new(v), span, signals, ty),
205
+
m,
206
+
)
207
+
})
208
+
.unwrap_or(PipelineData::Empty)
209
+
}
210
+
(_, _, None) => PipelineData::Empty,
211
+
},
212
+
PipelineData::ListStream(s, m) => {
213
+
let span = s.span();
214
+
let v = s
215
+
.into_iter()
216
+
.map(|val| val.unwrap_error().map_err(cmd_err))
217
+
.collect::<Result<Vec<Value>, _>>()?;
218
+
PipelineData::list_stream(ListStream::new(v.into_iter(), span, signals), m)
219
+
}
220
+
x => x,
221
+
};
222
+
223
+
// TODO: idk what this does i copied it from PipelineData::print_table
224
+
// dunno if it matters, we can just use nu_command::Table and it works fine i think
225
+
let table_command = engine_state
226
+
.table_decl_id
227
+
.map(|decl_id| engine_state.get_decl(decl_id))
228
+
.filter(|command| command.block_id().is_some())
229
+
.unwrap_or(&nu_command::Table);
230
let call = Call::new(pipeline_data.span().unwrap_or_else(Span::unknown));
231
232
let res = table_command
233
+
.run(engine_state, stack, &call, pipeline_data)
234
.map_err(cmd_err)?;
235
236
match res {
···
240
}
241
PipelineData::ByteStream(s, _) => {
242
for line in s.lines().into_iter().flatten() {
243
+
let out = line.map_err(cmd_err)?; // TODO: do we turn this into a Value ??? or is returning err fine
244
print_to_console(&out, true);
245
}
246
}
···
266
STACK.get().unwrap().lock().expect("stack initialized"),
267
);
268
269
+
match run_command_internal(&mut engine_guard, &mut stack_guard, input) {
270
+
Ok(_) => None,
271
+
Err(cmd_err) => Some(format_error(
272
+
cmd_err.error,
273
+
input.to_owned(),
274
+
cmd_err.start_offset,
275
+
)),
276
+
}
277
}
278
279
#[wasm_bindgen]