pub fn resolve<'a>(&'a self, property_set: &'a PropertySet) -> ResolveResult {
        match self {
            Expression::Equals(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.equals(val) },
            ),
            Expression::Less(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.less(val) },
            ),
            Expression::LessEqual(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.less_equal(val) },
            ),
            Expression::Greater(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.greater(val) },
            ),
            Expression::GreaterEqual(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.greater_equal(val) },
            ),
            // other binary operators here if needed...
            Expression::And(inner_expressions) => self.resolve_and(inner_expressions, property_set),
            Expression::Or(inner_expressions) => self.resolve_or(inner_expressions, property_set),
            Expression::Not(inner_expression) => match inner_expression.resolve(property_set) {
                ResolveResult::True => ResolveResult::False(vec![], Expression::Empty(false)),
                ResolveResult::False(_, _) => ResolveResult::True,
                ResolveResult::Undefined(un_props, unresolved_expr) => {
                    ResolveResult::Undefined(un_props, Expression::Not(Box::new(unresolved_expr)))
                }
                ResolveResult::Err(err) => ResolveResult::Err(err),
            },
            Expression::Present(attr) => self.resolve_present(attr, property_set),
            Expression::Empty(val) => {
                if *val {
                    ResolveResult::True
                } else {
                    ResolveResult::False(vec![], Expression::Empty(false))
                }
            }
        }
    }
// (DONE) Rework for adjusted property definition syntax (property types derived form literals)
// (DONE) Implement strong resolution and expression 'reduce' (ie. undefined results are propagated rather than ignored)
//       - (DONE) Refactor ResolveResult to include vector of PropertyRefs rather than plain strings...
// (DONE) Implement handling of unreduced expressions in "matching" results.
// (DONE) It may be useful to return list of properties which couldn't be resolved
// (DONE) Properties of some simple types plus binary operators.
// (DONE) Handling of Version simple type, need to implement operators.
// (DONE) Handling of Decimal simple type
// (DONE) Handling of List property type
// (DONE) equals operator for List property type with single operand (ignore other comparison operators)
// (DONE) equals operator for List property type with List operand (list equivalence operator)
// TODO: Handling of types in constraint filter expressions
// TODO: Implement allowed characters in property names
// (DONE) Rework resolve so that ResolveResult is based on strs and not Strings
// (DONE) wildcard matching of property values
// TODO: wildcard matching of value-less properties
//       - Implement dynamic property "handler" - via trait?
// (DONE) aspects
// TODO: finalize and review the matching relation implementations
(DONE) Rework for adjusted property definition syntax (property types derived form literals)
(DONE) Implement strong resolution and expression 'reduce'
(DONE) Refactor ResolveResult to include vector of PropertyRefs rather than plain strings
(DONE) Implement handling of unreduced expressions in "matching" results.
(DONE) It may be useful to return list of properties which couldn't be resolved
(DONE) Properties of some simple types plus binary operators.
(DONE) Handling of Version simple type, need to implement operators.
( DONE ) Rework for adjusted property definition syntax ( property types derived form literals ) ( DONE ) Implement strong resolution and expression ' reduce ' ( DONE ) Refactor ResolveResult to include vector of PropertyRefs rather than plain strings ( DONE ) Implement handling of unreduced expressions in " matching " results . ( DONE ) It may be useful to return list of properties which couldn ' t be resolved ( DONE ) Properties of some simple types plus binary operators . ( DONE ) Handling of Version simple type need to implement operators .
pub fn resolve<'a>(&'a self, property_set: &'a PropertySet) -> ResolveResult {
        match self {
            Expression::Equals(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.equals(val) },
            ),
            Expression::Less(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.less(val) },
            ),
            Expression::LessEqual(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.less_equal(val) },
            ),
            Expression::Greater(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.greater(val) },
            ),
            Expression::GreaterEqual(attr, val) => self.resolve_with_function(
                attr,
                val,
                property_set,
                |prop_value: &PropertyValue, val: &str| -> bool { prop_value.greater_equal(val) },
            ),
            // other binary operators here if needed...
            Expression::And(inner_expressions) => self.resolve_and(inner_expressions, property_set),
            Expression::Or(inner_expressions) => self.resolve_or(inner_expressions, property_set),
            Expression::Not(inner_expression) => match inner_expression.resolve(property_set) {
                ResolveResult::True => ResolveResult::False(vec![], Expression::Empty(false)),
                ResolveResult::False(_, _) => ResolveResult::True,
                ResolveResult::Undefined(un_props, unresolved_expr) => {
                    ResolveResult::Undefined(un_props, Expression::Not(Box::new(unresolved_expr)))
                }
                ResolveResult::Err(err) => ResolveResult::Err(err),
            },
            Expression::Present(attr) => self.resolve_present(attr, property_set),
            Expression::Empty(val) => {
                if *val {
                    ResolveResult::True
                } else {
                    ResolveResult::False(vec![], Expression::Empty(false))
                }
            }
        }
    }
pub fn resolve < ' a > ( & ' a self , property_set : & ' a PropertySet ) -> ResolveResult { match self { Expression :: Equals ( attr , val ) => self . resolve_with_function ( attr , val , property_set , | prop_value : & PropertyValue , val : & str | -> bool { prop_value . equals ( val ) } , ) , Expression :: Less ( attr , val ) => self . resolve_with_function ( attr , val , property_set , | prop_value : & PropertyValue , val : & str | -> bool { prop_value . less ( val ) } , ) , Expression :: LessEqual ( attr , val ) => self . resolve_with_function ( attr , val , property_set , | prop_value : & PropertyValue , val : & str | -> bool { prop_value . less_equal ( val ) } , ) , Expression :: Greater ( attr , val ) => self . resolve_with_function ( attr , val , property_set , | prop_value : & PropertyValue , val : & str | -> bool { prop_value . greater ( val ) } , ) , Expression :: GreaterEqual ( attr , val ) => self . resolve_with_function ( attr , val , property_set , | prop_value : & PropertyValue , val : & str | -> bool { prop_value . greater_equal ( val ) } , ) , // other binary operators here if needed... Expression :: And ( inner_expressions ) => self . resolve_and ( inner_expressions , property_set ) , Expression :: Or ( inner_expressions ) => self . resolve_or ( inner_expressions , property_set ) , Expression :: Not ( inner_expression ) => match inner_expression . resolve ( property_set ) { ResolveResult :: True => ResolveResult :: False ( vec ! [ ] , Expression :: Empty ( false ) ) , ResolveResult :: False ( _ , _ ) => ResolveResult :: True , ResolveResult :: Undefined ( un_props , unresolved_expr ) => { ResolveResult :: Undefined ( un_props , Expression :: Not ( Box :: new ( unresolved_expr ) ) ) } ResolveResult :: Err ( err ) => ResolveResult :: Err ( err ) , } , Expression :: Present ( attr ) => self . resolve_present ( attr , property_set ) , Expression :: Empty ( val ) => { if * val { ResolveResult :: True } else { ResolveResult :: False ( vec ! [ ] , Expression :: Empty ( false ) ) } } } }
(DONE) Rework for adjusted property definition syntax (property types derived form literals)
(DONE) Implement strong resolution and expression 'reduce' (ie.
( DONE ) Rework for adjusted property definition syntax ( property types derived form literals ) ( DONE ) Implement strong resolution and expression ' reduce ' ( ie .
&'a self
property_set
&'a PropertySet
&'a self
property_set
&'a PropertySet