round trip call info

This commit is contained in:
Fernando Herrera 2021-10-30 11:19:16 +01:00
parent f301f686b5
commit 9838154ad1
2 changed files with 74 additions and 8 deletions

View File

@ -1,7 +1,8 @@
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{ShellError, Signature, Value};
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{PipelineData, ShellError, Signature};
#[derive(Clone)]
pub struct RunPlugin;
impl Command for RunPlugin {
@ -19,10 +20,11 @@ impl Command for RunPlugin {
fn run(
&self,
_context: &EvaluationContext,
_context: &EngineState,
_stack: &mut Stack,
_call: &Call,
_input: Value,
) -> Result<nu_protocol::Value, ShellError> {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Err(ShellError::InternalError("plugin".into()))
}
}

View File

@ -3,6 +3,12 @@ use crate::value_capnp::call_info;
use capnp::serialize_packed;
use nu_protocol::{ast::Call, ShellError, Value};
#[derive(Debug)]
pub struct CallInfo {
pub call: Call,
pub input: Value,
}
pub fn write_buffer(
call: &Call,
input: &Value,
@ -30,6 +36,31 @@ pub fn write_buffer(
.map_err(|e| ShellError::EncodingError(e.to_string()))
}
pub fn read_buffer(reader: &mut impl std::io::BufRead) -> Result<CallInfo, ShellError> {
let message_reader =
serialize_packed::read_message(reader, ::capnp::message::ReaderOptions::new()).unwrap();
let reader = message_reader
.get_root::<call_info::Reader>()
.map_err(|e| ShellError::DecodingError(e.to_string()))?;
let call_reader = reader
.get_call()
.map_err(|e| ShellError::DecodingError(e.to_string()))?;
let call = call::deserialize_call(call_reader)
.map_err(|e| ShellError::DecodingError(e.to_string()))?;
let value_reader = reader
.get_input()
.map_err(|e| ShellError::DecodingError(e.to_string()))?;
let input = value::deserialize_value(value_reader)
.map_err(|e| ShellError::DecodingError(e.to_string()))?;
Ok(CallInfo { call, input })
}
#[cfg(test)]
mod tests {
use super::*;
@ -38,9 +69,19 @@ mod tests {
Span, Spanned, Value,
};
fn compare_expressions(lhs: &Expression, rhs: &Expression) {
match (&lhs.expr, &rhs.expr) {
(Expr::Bool(a), Expr::Bool(b)) => assert_eq!(a, b),
(Expr::Int(a), Expr::Int(b)) => assert_eq!(a, b),
(Expr::Float(a), Expr::Float(b)) => assert_eq!(a, b),
(Expr::String(a), Expr::String(b)) => assert_eq!(a, b),
_ => panic!("not matching values"),
}
}
#[test]
fn callinfo_round_trip() {
let value = Value::Bool {
let input = Value::Bool {
val: false,
span: Span { start: 1, end: 20 },
};
@ -77,7 +118,30 @@ mod tests {
};
let mut buffer: Vec<u8> = Vec::new();
write_buffer(&call, &value, &mut buffer).expect("unable to serialize message");
println!("{:?}", buffer);
write_buffer(&call, &input, &mut buffer).expect("unable to serialize message");
let call_info = read_buffer(&mut buffer.as_slice()).expect("unable to read message");
assert_eq!(input, call_info.input);
assert_eq!(call.head, call_info.call.head);
assert_eq!(call.positional.len(), call_info.call.positional.len());
call.positional
.iter()
.zip(call_info.call.positional.iter())
.for_each(|(lhs, rhs)| compare_expressions(lhs, rhs));
call.named
.iter()
.zip(call_info.call.named.iter())
.for_each(|(lhs, rhs)| {
// Comparing the keys
assert_eq!(lhs.0.item, rhs.0.item);
match (&lhs.1, &rhs.1) {
(None, None) => {}
(Some(a), Some(b)) => compare_expressions(a, b),
_ => panic!("not matching values"),
}
});
}
}