mirror of
https://github.com/nushell/nushell
synced 2025-01-15 14:44:14 +00:00
encode list
This commit is contained in:
parent
5a1d99cefb
commit
36a834c1e3
1 changed files with 122 additions and 82 deletions
|
@ -8,79 +8,55 @@ pub mod plugin_value {
|
||||||
use capnp::serialize_packed;
|
use capnp::serialize_packed;
|
||||||
use nu_protocol::{Span, Value};
|
use nu_protocol::{Span, Value};
|
||||||
|
|
||||||
pub fn serialize_value(value: &Value, writer: &mut impl std::io::Write) -> capnp::Result<()> {
|
pub fn serialize_message(value: &Value, writer: &mut impl std::io::Write) -> capnp::Result<()> {
|
||||||
let mut message = ::capnp::message::Builder::new_default();
|
let mut message = ::capnp::message::Builder::new_default();
|
||||||
|
|
||||||
{
|
let mut builder = message.init_root::<value::Builder>();
|
||||||
let mut serialized_value = message.init_root::<value::Builder>();
|
|
||||||
|
|
||||||
let value_span = match value {
|
let value_span = serialize_value(value, builder.reborrow());
|
||||||
Value::Nothing { span } => {
|
let mut span = builder.reborrow().init_span();
|
||||||
serialized_value.set_void(());
|
|
||||||
*span
|
|
||||||
}
|
|
||||||
Value::Bool { val, span } => {
|
|
||||||
serialized_value.set_bool(*val);
|
|
||||||
*span
|
|
||||||
}
|
|
||||||
Value::Int { val, span } => {
|
|
||||||
serialized_value.set_int(*val);
|
|
||||||
*span
|
|
||||||
}
|
|
||||||
Value::Float { val, span } => {
|
|
||||||
serialized_value.set_float(*val);
|
|
||||||
*span
|
|
||||||
}
|
|
||||||
Value::String { val, span } => {
|
|
||||||
serialized_value.set_string(&val);
|
|
||||||
*span
|
|
||||||
}
|
|
||||||
Value::List { vals, span } => {
|
|
||||||
{
|
|
||||||
serialize_list(vals, &mut serialized_value);
|
|
||||||
}
|
|
||||||
*span
|
|
||||||
}
|
|
||||||
_ => Span::unknown(),
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut span = serialized_value.reborrow().init_span();
|
|
||||||
span.set_start(value_span.start as u64);
|
span.set_start(value_span.start as u64);
|
||||||
span.set_end(value_span.end as u64);
|
span.set_end(value_span.end as u64);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serialize_packed::write_message(writer, &message)
|
serialize_packed::write_message(writer, &message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_list(vals: &[Value], builder: &mut value::Builder) {
|
fn serialize_value(value: &Value, mut builder: value::Builder) -> Span {
|
||||||
|
match value {
|
||||||
|
Value::Nothing { span } => {
|
||||||
|
builder.set_void(());
|
||||||
|
*span
|
||||||
|
}
|
||||||
|
Value::Bool { val, span } => {
|
||||||
|
builder.set_bool(*val);
|
||||||
|
*span
|
||||||
|
}
|
||||||
|
Value::Int { val, span } => {
|
||||||
|
builder.set_int(*val);
|
||||||
|
*span
|
||||||
|
}
|
||||||
|
Value::Float { val, span } => {
|
||||||
|
builder.set_float(*val);
|
||||||
|
*span
|
||||||
|
}
|
||||||
|
Value::String { val, span } => {
|
||||||
|
builder.set_string(&val);
|
||||||
|
*span
|
||||||
|
}
|
||||||
|
Value::List { vals, span } => {
|
||||||
let mut list_builder = builder.reborrow().init_list(vals.len() as u32);
|
let mut list_builder = builder.reborrow().init_list(vals.len() as u32);
|
||||||
|
for (index, value) in vals.iter().enumerate() {
|
||||||
|
let inner_builder = list_builder.reborrow().get(index as u32);
|
||||||
|
serialize_value(value, inner_builder);
|
||||||
|
}
|
||||||
|
|
||||||
for (index, val) in vals.iter().enumerate() {
|
*span
|
||||||
match val {
|
|
||||||
Value::Nothing { .. } => {
|
|
||||||
list_builder.reborrow().get(index as u32).set_void(());
|
|
||||||
}
|
|
||||||
Value::Bool { val, .. } => {
|
|
||||||
list_builder.reborrow().get(index as u32).set_bool(*val);
|
|
||||||
}
|
|
||||||
Value::Int { val, .. } => {
|
|
||||||
list_builder.reborrow().get(index as u32).set_int(*val);
|
|
||||||
}
|
|
||||||
Value::Float { val, .. } => {
|
|
||||||
list_builder.reborrow().get(index as u32).set_float(*val);
|
|
||||||
}
|
|
||||||
Value::String { val, .. } => {
|
|
||||||
list_builder.reborrow().get(index as u32).set_string(val);
|
|
||||||
}
|
|
||||||
Value::List { vals, .. } => serialize_list(vals, builder),
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
_ => Span::unknown(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_value(reader: &mut impl std::io::BufRead) -> Value {
|
pub fn deserialize_message(reader: &mut impl std::io::BufRead) -> Value {
|
||||||
let message_reader =
|
let message_reader =
|
||||||
serialize_packed::read_message(reader, ::capnp::message::ReaderOptions::new()).unwrap();
|
serialize_packed::read_message(reader, ::capnp::message::ReaderOptions::new()).unwrap();
|
||||||
|
|
||||||
|
@ -92,7 +68,11 @@ pub mod plugin_value {
|
||||||
end: span_reader.get_end() as usize,
|
end: span_reader.get_end() as usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
match plugin_value.which() {
|
deserialize_value(span, plugin_value.reborrow())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_value(span: Span, reader: value::Reader) -> Value {
|
||||||
|
match reader.which() {
|
||||||
Ok(value::Void(())) => Value::Nothing { span },
|
Ok(value::Void(())) => Value::Nothing { span },
|
||||||
Ok(value::Bool(val)) => Value::Bool { val, span },
|
Ok(value::Bool(val)) => Value::Bool { val, span },
|
||||||
Ok(value::Int(val)) => Value::Int { val, span },
|
Ok(value::Int(val)) => Value::Int { val, span },
|
||||||
|
@ -101,9 +81,32 @@ pub mod plugin_value {
|
||||||
val: val.unwrap().to_string(),
|
val: val.unwrap().to_string(),
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
Ok(value::List(_)) => Value::Nothing {
|
Ok(value::List(vals)) => {
|
||||||
|
let values = vals.expect("something");
|
||||||
|
|
||||||
|
let values_list = values
|
||||||
|
.iter()
|
||||||
|
.map(|value| match value.which() {
|
||||||
|
Ok(value::Void(())) => Value::Nothing { span },
|
||||||
|
Ok(value::Bool(val)) => Value::Bool { val, span },
|
||||||
|
Ok(value::Int(val)) => Value::Int { val, span },
|
||||||
|
Ok(value::Float(val)) => Value::Float { val, span },
|
||||||
|
Ok(value::String(val)) => Value::String {
|
||||||
|
val: val.unwrap().to_string(),
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
Ok(value::List(_)) => Value::Nothing { span },
|
||||||
|
Err(capnp::NotInSchema(_)) => Value::Nothing {
|
||||||
span: Span::unknown(),
|
span: Span::unknown(),
|
||||||
},
|
},
|
||||||
|
})
|
||||||
|
.collect::<Vec<Value>>();
|
||||||
|
|
||||||
|
Value::List {
|
||||||
|
vals: values_list,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(capnp::NotInSchema(_)) => Value::Nothing {
|
Err(capnp::NotInSchema(_)) => Value::Nothing {
|
||||||
span: Span::unknown(),
|
span: Span::unknown(),
|
||||||
},
|
},
|
||||||
|
@ -139,13 +142,15 @@ mod tests {
|
||||||
|
|
||||||
for value in values {
|
for value in values {
|
||||||
let mut buffer: Vec<u8> = Vec::new();
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
plugin_value::serialize_value(&value, &mut buffer).expect("unable to write message");
|
plugin_value::serialize_message(&value, &mut buffer).expect("unable to write message");
|
||||||
let returned_value = plugin_value::deserialize_value(&mut buffer.as_slice());
|
let returned_value = plugin_value::deserialize_message(&mut buffer.as_slice());
|
||||||
|
|
||||||
assert_eq!(value, returned_value)
|
assert_eq!(value, returned_value)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
#[test]
|
||||||
|
fn value_nothing_round_trip() {
|
||||||
// Since nothing doesn't implement PartialOrd, we only compare that the
|
// Since nothing doesn't implement PartialOrd, we only compare that the
|
||||||
// encoded and decoded spans are correct
|
// encoded and decoded spans are correct
|
||||||
let value = Value::Nothing {
|
let value = Value::Nothing {
|
||||||
|
@ -153,8 +158,44 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut buffer: Vec<u8> = Vec::new();
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
plugin_value::serialize_value(&value, &mut buffer).expect("unable to write message");
|
plugin_value::serialize_message(&value, &mut buffer).expect("unable to write message");
|
||||||
let returned_value = plugin_value::deserialize_value(&mut buffer.as_slice());
|
let returned_value = plugin_value::deserialize_message(&mut buffer.as_slice());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
value.span().expect("span"),
|
||||||
|
returned_value.span().expect("span")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_round_trip() {
|
||||||
|
let values = vec![
|
||||||
|
Value::Bool {
|
||||||
|
val: false,
|
||||||
|
span: Span { start: 1, end: 20 },
|
||||||
|
},
|
||||||
|
Value::Int {
|
||||||
|
val: 10,
|
||||||
|
span: Span { start: 2, end: 30 },
|
||||||
|
},
|
||||||
|
Value::Float {
|
||||||
|
val: 10.0,
|
||||||
|
span: Span { start: 3, end: 40 },
|
||||||
|
},
|
||||||
|
Value::String {
|
||||||
|
val: "a string".into(),
|
||||||
|
span: Span { start: 4, end: 50 },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let value = Value::List {
|
||||||
|
vals: values,
|
||||||
|
span: Span { start: 1, end: 10 },
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
|
plugin_value::serialize_message(&value, &mut buffer).expect("unable to write message");
|
||||||
|
let returned_value = plugin_value::deserialize_message(&mut buffer.as_slice());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
value.span().expect("span"),
|
value.span().expect("span"),
|
||||||
|
@ -162,4 +203,3 @@ mod tests {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue