#![forbid(unsafe_code)]
use prost_types::{ListValue, Value};
pub trait ListValueExt {
fn from_vec(values: Vec<Value>) -> ListValue;
fn iter(&self) -> impl Iterator<Item = &Value> + '_;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn get(&self, index: usize) -> Option<&Value>;
}
impl ListValueExt for ListValue {
fn from_vec(values: Vec<Value>) -> ListValue {
ListValue { values }
}
fn iter(&self) -> impl Iterator<Item = &Value> + '_ {
self.values.iter()
}
fn len(&self) -> usize {
self.values.len()
}
fn is_empty(&self) -> bool {
self.values.is_empty()
}
fn get(&self, index: usize) -> Option<&Value> {
self.values.get(index)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::wrappers::ValueExt;
#[test]
fn from_vec_and_len() {
let vals = vec![Value::from_bool(true), Value::from_f64(42.0)];
let lv = ListValue::from_vec(vals);
assert_eq!(lv.len(), 2);
assert!(!lv.is_empty());
}
#[test]
fn empty_list() {
let lv = ListValue::from_vec(vec![]);
assert_eq!(lv.len(), 0);
assert!(lv.is_empty());
}
#[test]
fn iter_and_get() {
let vals = vec![
Value::from_f64(1.0),
Value::from_f64(2.0),
Value::from_f64(3.0),
];
let lv = ListValue::from_vec(vals);
let numbers: Vec<f64> = lv.iter().filter_map(|v| v.as_number()).collect();
assert_eq!(numbers, vec![1.0, 2.0, 3.0]);
assert_eq!(lv.get(0).and_then(|v| v.as_number()), Some(1.0));
assert_eq!(lv.get(2).and_then(|v| v.as_number()), Some(3.0));
assert!(lv.get(10).is_none());
}
}