Let 'to toml' output block source (#763)

This commit is contained in:
JT 2022-01-17 03:25:12 -05:00 committed by GitHub
parent c55b6c5ed5
commit 0f85646d8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -30,19 +30,19 @@ impl Command for ToToml {
fn run( fn run(
&self, &self,
_engine_state: &EngineState, engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, call: &Call,
input: PipelineData, input: PipelineData,
) -> Result<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
to_toml(input, head) to_toml(engine_state, input, head)
} }
} }
// Helper method to recursively convert nu_protocol::Value -> toml::Value // Helper method to recursively convert nu_protocol::Value -> toml::Value
// This shouldn't be called at the top-level // This shouldn't be called at the top-level
fn helper(v: &Value) -> Result<toml::Value, ShellError> { fn helper(engine_state: &EngineState, v: &Value) -> Result<toml::Value, ShellError> {
Ok(match &v { Ok(match &v {
Value::Bool { val, .. } => toml::Value::Boolean(*val), Value::Bool { val, .. } => toml::Value::Boolean(*val),
Value::Int { val, .. } => toml::Value::Integer(*val), Value::Int { val, .. } => toml::Value::Integer(*val),
@ -55,12 +55,16 @@ fn helper(v: &Value) -> Result<toml::Value, ShellError> {
Value::Record { cols, vals, .. } => { Value::Record { cols, vals, .. } => {
let mut m = toml::map::Map::new(); let mut m = toml::map::Map::new();
for (k, v) in cols.iter().zip(vals.iter()) { for (k, v) in cols.iter().zip(vals.iter()) {
m.insert(k.clone(), helper(v)?); m.insert(k.clone(), helper(engine_state, v)?);
} }
toml::Value::Table(m) toml::Value::Table(m)
} }
Value::List { vals, .. } => toml::Value::Array(toml_list(vals)?), Value::List { vals, .. } => toml::Value::Array(toml_list(engine_state, vals)?),
Value::Block { .. } => toml::Value::String("<Block>".to_string()), Value::Block { span, .. } => {
let code = engine_state.get_span_contents(span);
let code = String::from_utf8_lossy(code).to_string();
toml::Value::String(code)
}
Value::Nothing { .. } => toml::Value::String("<Nothing>".to_string()), Value::Nothing { .. } => toml::Value::String("<Nothing>".to_string()),
Value::Error { error } => return Err(error.clone()), Value::Error { error } => return Err(error.clone()),
Value::Binary { val, .. } => toml::Value::Array( Value::Binary { val, .. } => toml::Value::Array(
@ -81,11 +85,11 @@ fn helper(v: &Value) -> Result<toml::Value, ShellError> {
}) })
} }
fn toml_list(input: &[Value]) -> Result<Vec<toml::Value>, ShellError> { fn toml_list(engine_state: &EngineState, input: &[Value]) -> Result<Vec<toml::Value>, ShellError> {
let mut out = vec![]; let mut out = vec![];
for value in input { for value in input {
out.push(helper(value)?); out.push(helper(engine_state, value)?);
} }
Ok(out) Ok(out)
@ -109,11 +113,15 @@ fn toml_into_pipeline_data(
} }
} }
fn value_to_toml_value(v: &Value, head: Span) -> Result<toml::Value, ShellError> { fn value_to_toml_value(
engine_state: &EngineState,
v: &Value,
head: Span,
) -> Result<toml::Value, ShellError> {
match v { match v {
Value::Record { .. } => helper(v), Value::Record { .. } => helper(engine_state, v),
Value::List { ref vals, span } => match &vals[..] { Value::List { ref vals, span } => match &vals[..] {
[Value::Record { .. }, _end @ ..] => helper(v), [Value::Record { .. }, _end @ ..] => helper(engine_state, v),
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput(
"Expected a table with TOML-compatible structure from pipeline".to_string(), "Expected a table with TOML-compatible structure from pipeline".to_string(),
*span, *span,
@ -135,10 +143,14 @@ fn value_to_toml_value(v: &Value, head: Span) -> Result<toml::Value, ShellError>
} }
} }
fn to_toml(input: PipelineData, span: Span) -> Result<PipelineData, ShellError> { fn to_toml(
engine_state: &EngineState,
input: PipelineData,
span: Span,
) -> Result<PipelineData, ShellError> {
let value = input.into_value(span); let value = input.into_value(span);
let toml_value = value_to_toml_value(&value, span)?; let toml_value = value_to_toml_value(engine_state, &value, span)?;
match toml_value { match toml_value {
toml::Value::Array(ref vec) => match vec[..] { toml::Value::Array(ref vec) => match vec[..] {
[toml::Value::Table(_)] => toml_into_pipeline_data( [toml::Value::Table(_)] => toml_into_pipeline_data(
@ -170,6 +182,8 @@ mod tests {
// Positive Tests // Positive Tests
// //
let engine_state = EngineState::new();
let mut m = indexmap::IndexMap::new(); let mut m = indexmap::IndexMap::new();
m.insert("rust".to_owned(), Value::test_string("editor")); m.insert("rust".to_owned(), Value::test_string("editor"));
m.insert("is".to_owned(), Value::nothing(Span::test_data())); m.insert("is".to_owned(), Value::nothing(Span::test_data()));
@ -181,6 +195,7 @@ mod tests {
}, },
); );
let tv = value_to_toml_value( let tv = value_to_toml_value(
&engine_state,
&Value::from(Spanned { &Value::from(Spanned {
item: m, item: m,
span: Span::test_data(), span: Span::test_data(),
@ -197,6 +212,7 @@ mod tests {
); );
// TOML string // TOML string
let tv = value_to_toml_value( let tv = value_to_toml_value(
&engine_state,
&Value::test_string( &Value::test_string(
r#" r#"
title = "TOML Example" title = "TOML Example"
@ -221,9 +237,14 @@ mod tests {
// //
// Negative Tests // Negative Tests
// //
value_to_toml_value(&Value::test_string("not_valid"), Span::test_data())
.expect_err("Expected non-valid toml (String) to cause error!");
value_to_toml_value( value_to_toml_value(
&engine_state,
&Value::test_string("not_valid"),
Span::test_data(),
)
.expect_err("Expected non-valid toml (String) to cause error!");
value_to_toml_value(
&engine_state,
&Value::List { &Value::List {
vals: vec![Value::test_string("1")], vals: vec![Value::test_string("1")],
span: Span::test_data(), span: Span::test_data(),