Add trait to allow iterating over all variables in a context.
Both iterating with and without values is supported. Due to limitations in the language, currently only iterating by cloning is supported. When GATs are stabilised, this should change. Relates to #108
This commit is contained in:
parent
3d60c66305
commit
4cc86e7683
@ -4,7 +4,7 @@
|
|||||||
//! This crate implements two basic variants, the `EmptyContext`, that returns `None` for each identifier and cannot be manipulated, and the `HashMapContext`, that stores its mappings in hash maps.
|
//! This crate implements two basic variants, the `EmptyContext`, that returns `None` for each identifier and cannot be manipulated, and the `HashMapContext`, that stores its mappings in hash maps.
|
||||||
//! The HashMapContext is type-safe and returns an error if the user tries to assign a value of a different type than before to an identifier.
|
//! The HashMapContext is type-safe and returns an error if the user tries to assign a value of a different type than before to an identifier.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, iter};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
function::Function,
|
function::Function,
|
||||||
@ -40,6 +40,22 @@ pub trait ContextWithMutableFunctions: Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A context that allows to iterate over its variable names with their values.
|
||||||
|
///
|
||||||
|
/// **Note:** this trait will change after GATs are stabilised, because then we can get rid of the lifetime in the trait definition.
|
||||||
|
pub trait IterateVariablesContext<'a> {
|
||||||
|
/// The iterator type for iterating over variable name-value pairs.
|
||||||
|
type VariableIterator: 'a + Iterator<Item = (String, Value)>;
|
||||||
|
/// The iterator type for iterating over variable names.
|
||||||
|
type VariableNameIterator: 'a + Iterator<Item = String>;
|
||||||
|
|
||||||
|
/// Returns an iterator over pairs of variable names and values.
|
||||||
|
fn iter_variables(&'a self) -> Self::VariableIterator;
|
||||||
|
|
||||||
|
/// Returns an iterator over variable names.
|
||||||
|
fn iter_variable_names(&'a self) -> Self::VariableNameIterator;
|
||||||
|
}
|
||||||
|
|
||||||
/*/// A context that allows to retrieve functions programmatically.
|
/*/// A context that allows to retrieve functions programmatically.
|
||||||
pub trait GetFunctionContext: Context {
|
pub trait GetFunctionContext: Context {
|
||||||
/// Returns the function that is linked to the given identifier.
|
/// Returns the function that is linked to the given identifier.
|
||||||
@ -65,6 +81,19 @@ impl Context for EmptyContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> IterateVariablesContext<'a> for EmptyContext {
|
||||||
|
type VariableIterator = iter::Empty<(String, Value)>;
|
||||||
|
type VariableNameIterator = iter::Empty<String>;
|
||||||
|
|
||||||
|
fn iter_variables(&self) -> Self::VariableIterator {
|
||||||
|
iter::empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_variable_names(&self) -> Self::VariableNameIterator {
|
||||||
|
iter::empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A context that stores its mappings in hash maps.
|
/// A context that stores its mappings in hash maps.
|
||||||
///
|
///
|
||||||
/// *Value and function mappings are stored independently, meaning that there can be a function and a value with the same identifier.*
|
/// *Value and function mappings are stored independently, meaning that there can be a function and a value with the same identifier.*
|
||||||
@ -125,6 +154,25 @@ impl ContextWithMutableFunctions for HashMapContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> IterateVariablesContext<'a> for HashMapContext {
|
||||||
|
type VariableIterator = std::iter::Map<
|
||||||
|
std::collections::hash_map::Iter<'a, String, Value>,
|
||||||
|
fn((&String, &Value)) -> (String, Value),
|
||||||
|
>;
|
||||||
|
type VariableNameIterator =
|
||||||
|
std::iter::Cloned<std::collections::hash_map::Keys<'a, String, Value>>;
|
||||||
|
|
||||||
|
fn iter_variables(&'a self) -> Self::VariableIterator {
|
||||||
|
self.variables
|
||||||
|
.iter()
|
||||||
|
.map(|(string, value)| (string.clone(), value.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_variable_names(&'a self) -> Self::VariableNameIterator {
|
||||||
|
self.variables.keys().cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This macro provides a convenient syntax for creating a static context.
|
/// This macro provides a convenient syntax for creating a static context.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -536,7 +536,7 @@ extern crate serde_derive;
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
context::{
|
context::{
|
||||||
Context, ContextWithMutableFunctions, ContextWithMutableVariables, EmptyContext,
|
Context, ContextWithMutableFunctions, ContextWithMutableVariables, EmptyContext,
|
||||||
HashMapContext,
|
HashMapContext, IterateVariablesContext,
|
||||||
},
|
},
|
||||||
error::{EvalexprError, EvalexprResult},
|
error::{EvalexprError, EvalexprResult},
|
||||||
function::Function,
|
function::Function,
|
||||||
|
Loading…
Reference in New Issue
Block a user