Rows and values can be checked for emptiness. Allows to set a value if desired. (#1665)

This commit is contained in:
Andrés N. Robalino
2020-04-26 12:30:52 -05:00
committed by GitHub
parent a62745eefb
commit 80025ea684
11 changed files with 437 additions and 98 deletions

View File

@ -3,6 +3,7 @@ mod convert;
mod debug;
pub mod dict;
pub mod evaluate;
pub mod iter;
pub mod primitive;
pub mod range;
mod serde_bigdecimal;
@ -11,6 +12,7 @@ mod serde_bigint;
use crate::hir;
use crate::type_name::{ShellTypeName, SpannedTypeName};
use crate::value::dict::Dictionary;
use crate::value::iter::{RowValueIter, TableValueIter};
use crate::value::primitive::Primitive;
use crate::value::range::{Range, RangeInclusion};
use crate::{ColumnPath, PathMember};
@ -313,6 +315,39 @@ impl Value {
_ => Err(ShellError::type_error("boolean", self.spanned_type_name())),
}
}
/// Returns an iterator of the values rows
pub fn table_entries(&self) -> TableValueIter<'_> {
crate::value::iter::table_entries(&self)
}
/// Returns an iterator of the value's cells
pub fn row_entries(&self) -> RowValueIter<'_> {
crate::value::iter::row_entries(&self)
}
/// Returns true if the value is empty
pub fn is_empty(&self) -> bool {
match &self {
Value {
value: UntaggedValue::Primitive(p),
..
} => p.is_empty(),
t
@
Value {
value: UntaggedValue::Table(_),
..
} => t.table_entries().all(|row| row.is_empty()),
r
@
Value {
value: UntaggedValue::Row(_),
..
} => r.row_entries().all(|(_, value)| value.is_empty()),
_ => false,
}
}
}
impl Into<Value> for String {

View File

@ -0,0 +1,50 @@
use crate::value::{UntaggedValue, Value};
pub enum RowValueIter<'a> {
Empty,
Entries(indexmap::map::Iter<'a, String, Value>),
}
pub enum TableValueIter<'a> {
Empty,
Entries(std::slice::Iter<'a, Value>),
}
impl<'a> Iterator for RowValueIter<'a> {
type Item = (&'a String, &'a Value);
fn next(&mut self) -> Option<Self::Item> {
match self {
RowValueIter::Empty => None,
RowValueIter::Entries(iter) => iter.next(),
}
}
}
impl<'a> Iterator for TableValueIter<'a> {
type Item = &'a Value;
fn next(&mut self) -> Option<Self::Item> {
match self {
TableValueIter::Empty => None,
TableValueIter::Entries(iter) => iter.next(),
}
}
}
pub fn table_entries(value: &Value) -> TableValueIter<'_> {
match &value.value {
UntaggedValue::Table(t) => TableValueIter::Entries(t.iter()),
_ => TableValueIter::Empty,
}
}
pub fn row_entries(value: &Value) -> RowValueIter<'_> {
match &value.value {
UntaggedValue::Row(o) => {
let iter = o.entries.iter();
RowValueIter::Entries(iter)
}
_ => RowValueIter::Empty,
}
}

View File

@ -84,6 +84,15 @@ impl Primitive {
)),
}
}
/// Returns true if the value is empty
pub fn is_empty(&self) -> bool {
match self {
Primitive::Nothing => true,
Primitive::String(s) => s.is_empty(),
_ => false,
}
}
}
impl num_traits::Zero for Primitive {