This commit is contained in:
JT
2021-10-25 17:01:02 +13:00
parent ab9d6b206d
commit b6d269e90a
63 changed files with 1075 additions and 1013 deletions

View File

@ -11,4 +11,5 @@ miette = "3.0.0"
serde = {version = "1.0.130", features = ["derive"]}
chrono = { version="0.4.19", features=["serde"] }
chrono-humanize = "0.2.1"
byte-unit = "4.0.9"
byte-unit = "4.0.9"
im = "15.0.0"

View File

@ -1,8 +1,8 @@
use crate::{ast::Call, value::Value, BlockId, Example, ShellError, Signature};
use crate::{ast::Call, value::Value, BlockId, Example, PipelineData, ShellError, Signature};
use super::EvaluationContext;
pub trait Command: Send + Sync {
pub trait Command: Send + Sync + CommandClone {
fn name(&self) -> &str;
fn signature(&self) -> Signature {
@ -19,8 +19,8 @@ pub trait Command: Send + Sync {
&self,
context: &EvaluationContext,
call: &Call,
input: Value,
) -> Result<Value, ShellError>;
input: PipelineData,
) -> Result<PipelineData, ShellError>;
fn is_binary(&self) -> bool {
false
@ -55,3 +55,22 @@ pub trait Command: Send + Sync {
None
}
}
pub trait CommandClone {
fn clone_box(&self) -> Box<dyn Command>;
}
impl<T> CommandClone for T
where
T: 'static + Command + Clone,
{
fn clone_box(&self) -> Box<dyn Command> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn Command> {
fn clone(&self) -> Box<dyn Command> {
self.clone_box()
}
}

View File

@ -3,13 +3,14 @@ use crate::{ast::Block, BlockId, DeclId, Example, Signature, Span, Type, VarId};
use core::panic;
use std::{collections::HashMap, slice::Iter};
#[derive(Clone)]
pub struct EngineState {
files: Vec<(String, usize, usize)>,
file_contents: Vec<u8>,
vars: Vec<Type>,
decls: Vec<Box<dyn Command>>,
blocks: Vec<Block>,
pub scope: Vec<ScopeFrame>,
files: im::Vector<(String, usize, usize)>,
file_contents: im::Vector<(Vec<u8>, usize, usize)>,
vars: im::Vector<Type>,
decls: im::Vector<Box<dyn Command + 'static>>,
blocks: im::Vector<Block>,
pub scope: im::Vector<ScopeFrame>,
}
// Tells whether a decl etc. is visible or not
@ -53,7 +54,7 @@ impl Visibility {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct ScopeFrame {
pub vars: HashMap<Vec<u8>, VarId>,
predecls: HashMap<Vec<u8>, DeclId>, // temporary storage for predeclarations
@ -95,12 +96,12 @@ impl Default for EngineState {
impl EngineState {
pub fn new() -> Self {
Self {
files: vec![],
file_contents: vec![],
vars: vec![],
decls: vec![],
blocks: vec![],
scope: vec![ScopeFrame::new()],
files: im::vector![],
file_contents: im::vector![],
vars: im::vector![],
decls: im::vector![],
blocks: im::vector![],
scope: im::vector![ScopeFrame::new()],
}
}
@ -112,7 +113,7 @@ impl EngineState {
this.vars.extend(delta.vars);
this.blocks.extend(delta.blocks);
if let Some(last) = this.scope.last_mut() {
if let Some(last) = this.scope.back_mut() {
let first = delta.scope.remove(0);
for item in first.decls.into_iter() {
last.decls.insert(item.0, item.1);
@ -165,8 +166,10 @@ impl EngineState {
}
pub fn print_contents(&self) {
let string = String::from_utf8_lossy(&self.file_contents);
println!("{}", string);
for (contents, _, _) in self.file_contents.iter() {
let string = String::from_utf8_lossy(&contents);
println!("{}", string);
}
}
pub fn find_decl(&self, name: &[u8]) -> Option<DeclId> {
@ -200,7 +203,13 @@ impl EngineState {
}
pub fn get_span_contents(&self, span: &Span) -> &[u8] {
&self.file_contents[span.start..span.end]
for (contents, start, finish) in &self.file_contents {
if span.start >= *start && span.start < *finish {
return &contents[(span.start - start)..(span.end - start)];
}
}
panic!("internal error: span missing in file contents cache")
}
pub fn get_var(&self, var_id: VarId) -> &Type {
@ -256,7 +265,7 @@ impl EngineState {
self.file_contents.len()
}
pub fn files(&self) -> Iter<(String, usize, usize)> {
pub fn files(&self) -> impl Iterator<Item = &(String, usize, usize)> {
self.files.iter()
}
@ -273,8 +282,11 @@ impl EngineState {
pub fn get_file_source(&self, file_id: usize) -> String {
for file in self.files.iter().enumerate() {
if file.0 == file_id {
let output =
String::from_utf8_lossy(&self.file_contents[file.1 .1..file.1 .2]).to_string();
let contents = self.get_span_contents(&Span {
start: file.1 .1,
end: file.1 .2,
});
let output = String::from_utf8_lossy(contents).to_string();
return output;
}
@ -286,12 +298,13 @@ impl EngineState {
#[allow(unused)]
pub(crate) fn add_file(&mut self, filename: String, contents: Vec<u8>) -> usize {
let next_span_start = self.next_span_start();
let next_span_end = next_span_start + contents.len();
self.file_contents.extend(&contents);
self.file_contents
.push_back((contents, next_span_start, next_span_end));
let next_span_end = self.next_span_start();
self.files.push((filename, next_span_start, next_span_end));
self.files
.push_back((filename, next_span_start, next_span_end));
self.num_files() - 1
}
@ -304,7 +317,7 @@ pub struct StateWorkingSet<'a> {
pub struct StateDelta {
files: Vec<(String, usize, usize)>,
pub(crate) file_contents: Vec<u8>,
pub(crate) file_contents: Vec<(Vec<u8>, usize, usize)>,
vars: Vec<Type>, // indexed by VarId
decls: Vec<Box<dyn Command>>, // indexed by DeclId
blocks: Vec<Block>, // indexed by BlockId
@ -520,10 +533,11 @@ impl<'a> StateWorkingSet<'a> {
pub fn add_file(&mut self, filename: String, contents: &[u8]) -> usize {
let next_span_start = self.next_span_start();
let next_span_end = next_span_start + contents.len();
self.delta.file_contents.extend(contents);
let next_span_end = self.next_span_start();
self.delta
.file_contents
.push((contents.to_vec(), next_span_start, next_span_end));
self.delta
.files
@ -535,10 +549,16 @@ impl<'a> StateWorkingSet<'a> {
pub fn get_span_contents(&self, span: Span) -> &[u8] {
let permanent_end = self.permanent_state.next_span_start();
if permanent_end <= span.start {
&self.delta.file_contents[(span.start - permanent_end)..(span.end - permanent_end)]
for (contents, start, finish) in &self.delta.file_contents {
if (span.start >= *start) && (span.start < *finish) {
return &contents[(span.start - permanent_end)..(span.end - permanent_end)];
}
}
} else {
&self.permanent_state.file_contents[span.start..span.end]
return self.permanent_state.get_span_contents(&span);
}
panic!("internal error: missing span contents in file cache")
}
pub fn enter_scope(&mut self) {

View File

@ -5,7 +5,7 @@ use crate::{Example, ShellError, Signature, Value, VarId};
#[derive(Clone)]
pub struct EvaluationContext {
pub engine_state: Rc<RefCell<EngineState>>,
pub engine_state: Box<EngineState>,
pub stack: Stack,
}
@ -21,25 +21,11 @@ impl EvaluationContext {
}
}
pub fn add_var(&self, var_id: VarId, value: Value) {
// We need to make values concreate before we assign them to variables, as stream values
// will drain and remain drained.
//
// TODO: find a good home for converting a stream->list when storing into a variable
// TODO: add ctrl-c support when setting a var
let value = match value {
Value::Stream { stream, span } => Value::List {
vals: stream.collect(),
span,
},
x => x,
};
pub fn add_var(&mut self, var_id: VarId, value: Value) {
self.stack.add_var(var_id, value);
}
pub fn add_env_var(&self, var: String, value: String) {
pub fn add_env_var(&mut self, var: String, value: String) {
self.stack.add_env_var(var, value);
}
@ -48,23 +34,22 @@ impl EvaluationContext {
}
pub fn get_signatures(&self) -> Vec<Signature> {
self.engine_state.borrow().get_signatures()
self.engine_state.get_signatures()
}
pub fn get_signatures_with_examples(&self) -> Vec<(Signature, Vec<Example>)> {
self.engine_state.borrow().get_signatures_with_examples()
self.engine_state.get_signatures_with_examples()
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct StackFrame {
pub vars: HashMap<VarId, Value>,
pub env_vars: HashMap<String, String>,
pub parent: Option<Stack>,
}
#[derive(Clone, Debug)]
pub struct Stack(Rc<RefCell<StackFrame>>);
pub struct Stack(Vec<StackFrame>);
impl Default for Stack {
fn default() -> Self {
@ -74,64 +59,77 @@ impl Default for Stack {
impl Stack {
pub fn new() -> Stack {
Stack(Rc::new(RefCell::new(StackFrame {
Stack(vec![StackFrame {
vars: HashMap::new(),
env_vars: HashMap::new(),
parent: None,
})))
}])
}
pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> {
let this = self.0.borrow();
match this.vars.get(&var_id) {
Some(v) => Ok(v.clone()),
_ => {
if let Some(parent) = &this.parent {
parent.get_var(var_id)
} else {
Err(ShellError::InternalError("variable not found".into()))
}
for frame in self.0.iter().rev() {
if let Some(v) = frame.vars.get(&var_id) {
return Ok(v.clone());
}
}
Err(ShellError::InternalError("variable not found".into()))
}
pub fn add_var(&self, var_id: VarId, value: Value) {
let mut this = self.0.borrow_mut();
this.vars.insert(var_id, value);
pub fn add_var(&mut self, var_id: VarId, value: Value) {
let frame = self
.0
.last_mut()
.expect("internal error: can't access stack frame");
frame.vars.insert(var_id, value);
}
pub fn add_env_var(&self, var: String, value: String) {
let mut this = self.0.borrow_mut();
this.env_vars.insert(var, value);
pub fn add_env_var(&mut self, var: String, value: String) {
let frame = self
.0
.last_mut()
.expect("internal error: can't access stack frame");
frame.env_vars.insert(var, value);
}
pub fn enter_scope(self) -> Stack {
Stack(Rc::new(RefCell::new(StackFrame {
pub fn enter_scope(&self) -> Stack {
// FIXME: VERY EXPENSIVE to clone entire stack
let mut output = self.clone();
output.0.push(StackFrame {
vars: HashMap::new(),
env_vars: HashMap::new(),
parent: Some(self),
})))
});
output
}
pub fn get_env_vars(&self) -> HashMap<String, String> {
self.0.borrow().env_vars.clone()
let mut output = HashMap::new();
for frame in &self.0 {
output.extend(frame.env_vars.clone().into_iter());
}
output
}
pub fn get_env_var(&self, name: &str) -> Option<String> {
self.0.borrow().env_vars.get(name).cloned()
for frame in self.0.iter().rev() {
if let Some(v) = frame.env_vars.get(name) {
return Some(v.to_string());
}
}
None
}
pub fn print_stack(&self) {
println!("===frame===");
println!("vars:");
for (var, val) in &self.0.borrow().vars {
println!(" {}: {:?}", var, val);
}
println!("env vars:");
for (var, val) in &self.0.borrow().env_vars {
println!(" {}: {:?}", var, val);
}
if let Some(parent) = &self.0.borrow().parent {
parent.print_stack()
for frame in self.0.iter().rev() {
println!("===frame===");
println!("vars:");
for (var, val) in &frame.vars {
println!(" {}: {:?}", var, val);
}
println!("env vars:");
for (var, val) in &frame.env_vars {
println!(" {}: {:?}", var, val);
}
}
}
}

View File

@ -2,6 +2,7 @@ pub mod ast;
pub mod engine;
mod example;
mod id;
mod pipeline_data;
mod shell_error;
mod signature;
mod span;
@ -12,6 +13,7 @@ pub use value::Value;
pub use example::*;
pub use id::*;
pub use pipeline_data::*;
pub use shell_error::*;
pub use signature::*;
pub use span::*;

View File

@ -0,0 +1,62 @@
use crate::{Span, Value, ValueStream};
pub enum PipelineData {
Value(Value),
Stream(ValueStream),
}
impl PipelineData {
pub fn new() -> PipelineData {
PipelineData::Value(Value::nothing())
}
pub fn into_value(self) -> Value {
match self {
PipelineData::Value(v) => v,
PipelineData::Stream(s) => Value::List {
vals: s.collect(),
span: Span::unknown(), // FIXME?
},
}
}
}
impl Default for PipelineData {
fn default() -> Self {
PipelineData::new()
}
}
impl Iterator for PipelineData {
type Item = Value;
fn next(&mut self) -> Option<Self::Item> {
match self {
PipelineData::Value(Value::Nothing { .. }) => None,
PipelineData::Value(v) => {
let prev = std::mem::take(v);
Some(prev)
}
PipelineData::Stream(stream) => stream.next(),
}
}
}
pub trait IntoPipelineData {
fn into_pipeline_data(self) -> PipelineData;
}
impl IntoPipelineData for Value {
fn into_pipeline_data(self) -> PipelineData {
PipelineData::Value(self)
}
}
impl<T> IntoPipelineData for T
where
T: Iterator<Item = Value> + Send + 'static,
{
fn into_pipeline_data(self) -> PipelineData {
PipelineData::Stream(ValueStream(Box::new(self)))
}
}

View File

@ -1,7 +1,9 @@
use crate::ast::Call;
use crate::engine::Command;
use crate::engine::CommandClone;
use crate::engine::EvaluationContext;
use crate::BlockId;
use crate::PipelineData;
use crate::SyntaxShape;
use crate::Value;
use crate::VarId;
@ -335,6 +337,7 @@ impl Signature {
}
}
#[derive(Clone)]
struct Predeclaration {
signature: Signature,
}
@ -356,12 +359,13 @@ impl Command for Predeclaration {
&self,
_context: &EvaluationContext,
_call: &Call,
_input: Value,
) -> Result<crate::Value, crate::ShellError> {
_input: PipelineData,
) -> Result<PipelineData, crate::ShellError> {
panic!("Internal error: can't run a predeclaration without a body")
}
}
#[derive(Clone)]
struct BlockCommand {
signature: Signature,
block_id: BlockId,
@ -384,8 +388,8 @@ impl Command for BlockCommand {
&self,
_context: &EvaluationContext,
_call: &Call,
_input: Value,
) -> Result<crate::Value, crate::ShellError> {
_input: PipelineData,
) -> Result<crate::PipelineData, crate::ShellError> {
panic!("Internal error: can't run custom command with 'run', use block_id");
}

View File

@ -59,10 +59,6 @@ pub enum Value {
vals: Vec<Value>,
span: Span,
},
Stream {
stream: ValueStream,
span: Span,
},
List {
vals: Vec<Value>,
span: Span,
@ -110,7 +106,6 @@ impl Value {
Value::Record { span, .. } => Ok(*span),
Value::List { span, .. } => Ok(*span),
Value::Block { span, .. } => Ok(*span),
Value::Stream { span, .. } => Ok(*span),
Value::Nothing { span, .. } => Ok(*span),
Value::Binary { span, .. } => Ok(*span),
Value::CellPath { span, .. } => Ok(*span),
@ -129,7 +124,6 @@ impl Value {
Value::Range { span, .. } => *span = new_span,
Value::String { span, .. } => *span = new_span,
Value::Record { span, .. } => *span = new_span,
Value::Stream { span, .. } => *span = new_span,
Value::List { span, .. } => *span = new_span,
Value::Block { span, .. } => *span = new_span,
Value::Nothing { span, .. } => *span = new_span,
@ -158,7 +152,6 @@ impl Value {
Value::List { .. } => Type::List(Box::new(Type::Unknown)), // FIXME
Value::Nothing { .. } => Type::Nothing,
Value::Block { .. } => Type::Block,
Value::Stream { .. } => Type::ValueStream,
Value::Error { .. } => Type::Error,
Value::Binary { .. } => Type::Binary,
Value::CellPath { .. } => Type::CellPath,
@ -186,7 +179,6 @@ impl Value {
Err(error) => format!("{:?}", error),
},
Value::String { val, .. } => val,
Value::Stream { stream, .. } => stream.into_string(),
Value::List { vals: val, .. } => format!(
"[{}]",
val.into_iter()
@ -228,7 +220,6 @@ impl Value {
}
},
Value::String { val, .. } => val,
Value::Stream { stream, .. } => stream.collect_string(),
Value::List { vals: val, .. } => val
.into_iter()
.map(|x| x.collect_string())
@ -274,13 +265,6 @@ impl Value {
return Err(ShellError::AccessBeyondEnd(val.len(), *origin_span));
}
}
Value::Stream { stream, .. } => {
if let Some(item) = stream.nth(*count) {
current = item;
} else {
return Err(ShellError::AccessBeyondEndOfStream(*origin_span));
}
}
x => {
return Err(ShellError::IncompatiblePathAccess(
format!("{}", x.get_type()),
@ -329,27 +313,6 @@ impl Value {
span: *span,
};
}
Value::Stream { stream, span } => {
let mut output = vec![];
for val in stream {
output.push(val.clone().follow_cell_path(&[PathMember::String {
val: column_name.clone(),
span: *origin_span,
}])?);
// if let Value::Record { cols, vals, .. } = val {
// for col in cols.iter().enumerate() {
// if col.1 == column_name {
// output.push(vals[col.0].clone());
// }
// }
// }
}
current = Value::List {
vals: output,
span: *span,
};
}
x => {
return Err(ShellError::IncompatiblePathAccess(
format!("{}", x.get_type()),
@ -374,64 +337,6 @@ impl Value {
}
}
pub fn map<F>(self, span: Span, mut f: F) -> Result<Value, ShellError>
where
Self: Sized,
F: FnMut(Self) -> Value + 'static,
{
match self {
Value::List { vals, .. } => Ok(Value::Stream {
stream: vals.into_iter().map(f).into_value_stream(),
span,
}),
Value::Stream { stream, .. } => Ok(Value::Stream {
stream: stream.map(f).into_value_stream(),
span,
}),
Value::Range { val, .. } => Ok(Value::Stream {
stream: val.into_range_iter()?.map(f).into_value_stream(),
span,
}),
v => {
let output = f(v);
match output {
Value::Error { error } => Err(error),
v => Ok(v),
}
}
}
}
pub fn flat_map<U, F>(self, span: Span, mut f: F) -> Value
where
Self: Sized,
U: IntoIterator<Item = Value>,
<U as IntoIterator>::IntoIter: 'static,
F: FnMut(Self) -> U + 'static,
{
match self {
Value::List { vals, .. } => Value::Stream {
stream: vals.into_iter().map(f).flatten().into_value_stream(),
span,
},
Value::Stream { stream, .. } => Value::Stream {
stream: stream.map(f).flatten().into_value_stream(),
span,
},
Value::Range { val, .. } => match val.into_range_iter() {
Ok(iter) => Value::Stream {
stream: iter.map(f).flatten().into_value_stream(),
span,
},
Err(error) => Value::Error { error },
},
v => Value::Stream {
stream: f(v).into_iter().into_value_stream(),
span,
},
}
}
pub fn string(val: impl Into<String>, span: Span) -> Value {
Value::String {
val: val.into(),
@ -460,6 +365,12 @@ impl Value {
}
}
impl Default for Value {
fn default() -> Self {
Value::nothing()
}
}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
// Compare two floating point numbers. The decision interval for equality is dynamically
@ -511,24 +422,6 @@ impl PartialOrd for Value {
..
},
) if lhs_headers == rhs_headers && lhs == rhs => Some(Ordering::Equal),
(Value::Stream { stream: lhs, .. }, Value::Stream { stream: rhs, .. }) => {
lhs.clone().partial_cmp(rhs.clone())
}
(Value::Stream { stream: lhs, .. }, Value::String { val: rhs, .. }) => {
lhs.clone().collect_string().partial_cmp(rhs)
}
(Value::String { val: lhs, .. }, Value::Stream { stream: rhs, .. }) => {
lhs.partial_cmp(&rhs.clone().collect_string())
}
// NOTE: This may look a bit strange, but a `Stream` is still just a `List`, it just
// happens to be in an iterator form instead of a concrete form. The contained values
// can be compared.
(Value::Stream { stream: lhs, .. }, Value::List { vals: rhs, .. }) => {
lhs.clone().collect::<Vec<Value>>().partial_cmp(rhs)
}
(Value::List { vals: lhs, .. }, Value::Stream { stream: rhs, .. }) => {
lhs.partial_cmp(&rhs.clone().collect::<Vec<Value>>())
}
(Value::Binary { val: lhs, .. }, Value::Binary { val: rhs, .. }) => {
lhs.partial_cmp(rhs)
}
@ -852,10 +745,6 @@ impl Value {
val: rhs.contains(lhs),
span,
}),
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
val: rhs.clone().any(|x| lhs == &x),
span,
}),
_ => Err(ShellError::OperatorMismatch {
op_span: op,
lhs_ty: self.get_type(),
@ -886,10 +775,6 @@ impl Value {
val: !rhs.contains(lhs),
span,
}),
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
val: rhs.clone().all(|x| lhs != &x),
span,
}),
_ => Err(ShellError::OperatorMismatch {
op_span: op,
lhs_ty: self.get_type(),

View File

@ -1,10 +1,7 @@
use crate::*;
use std::{cell::RefCell, fmt::Debug, rc::Rc};
use std::fmt::Debug;
use serde::{ser::SerializeSeq, Deserialize, Serialize};
#[derive(Clone)]
pub struct ValueStream(pub Rc<RefCell<dyn Iterator<Item = Value>>>);
pub struct ValueStream(pub Box<dyn Iterator<Item = Value> + Send + 'static>);
impl ValueStream {
pub fn into_string(self) -> String {
@ -22,8 +19,8 @@ impl ValueStream {
.join("\n")
}
pub fn from_stream(input: impl Iterator<Item = Value> + 'static) -> ValueStream {
ValueStream(Rc::new(RefCell::new(input)))
pub fn from_stream(input: impl Iterator<Item = Value> + Send + 'static) -> ValueStream {
ValueStream(Box::new(input))
}
}
@ -38,66 +35,66 @@ impl Iterator for ValueStream {
fn next(&mut self) -> Option<Self::Item> {
{
self.0.borrow_mut().next()
self.0.next()
}
}
}
impl Serialize for ValueStream {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(None)?;
// impl Serialize for ValueStream {
// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
// where
// S: serde::Serializer,
// {
// let mut seq = serializer.serialize_seq(None)?;
for element in self.0.borrow_mut().into_iter() {
seq.serialize_element(&element)?;
}
seq.end()
}
}
// for element in self.0.borrow_mut().into_iter() {
// seq.serialize_element(&element)?;
// }
// seq.end()
// }
// }
impl<'de> Deserialize<'de> for ValueStream {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(MySeqVisitor)
}
}
// impl<'de> Deserialize<'de> for ValueStream {
// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
// where
// D: serde::Deserializer<'de>,
// {
// deserializer.deserialize_seq(MySeqVisitor)
// }
// }
struct MySeqVisitor;
// struct MySeqVisitor;
impl<'a> serde::de::Visitor<'a> for MySeqVisitor {
type Value = ValueStream;
// impl<'a> serde::de::Visitor<'a> for MySeqVisitor {
// type Value = ValueStream;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a value stream")
}
// fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
// formatter.write_str("a value stream")
// }
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'a>,
{
let mut output: Vec<Value> = vec![];
// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
// where
// A: serde::de::SeqAccess<'a>,
// {
// let mut output: Vec<Value> = vec![];
while let Some(value) = seq.next_element()? {
output.push(value);
}
// while let Some(value) = seq.next_element()? {
// output.push(value);
// }
Ok(ValueStream(Rc::new(RefCell::new(output.into_iter()))))
}
}
// Ok(ValueStream(Rc::new(RefCell::new(output.into_iter()))))
// }
// }
pub trait IntoValueStream {
fn into_value_stream(self) -> ValueStream;
}
// pub trait IntoValueStream {
// fn into_value_stream(self) -> ValueStream;
// }
impl<T> IntoValueStream for T
where
T: Iterator<Item = Value> + 'static,
{
fn into_value_stream(self) -> ValueStream {
ValueStream::from_stream(self)
}
}
// impl<T> IntoValueStream for T
// where
// T: Iterator<Item = Value> + 'static,
// {
// fn into_value_stream(self) -> ValueStream {
// ValueStream::from_stream(self)
// }
// }