Skip to content

Commit d587d54

Browse files
authored
More string ops: startsWith/contains (#111)
* adds support for string operations startsWth/contains (and negations)
1 parent 82333a7 commit d587d54

6 files changed

Lines changed: 356 additions & 112 deletions

File tree

prefab.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ message Criterion {
166166
PROP_DOES_NOT_END_WITH_ONE_OF = 9;
167167
HIERARCHICAL_MATCH = 10;
168168
IN_INT_RANGE = 11;
169+
PROP_STARTS_WITH_ONE_OF = 12;
170+
PROP_DOES_NOT_START_WITH_ONE_OF =13;
171+
PROP_CONTAINS_ONE_OF = 14;
172+
PROP_DOES_NOT_CONTAIN_ONE_OF = 15;
173+
PROP_LESS_THAN = 16;
174+
PROP_LESS_THAN_OR_EQUAL = 17;
175+
PROP_GREATER_THAN = 18;
176+
PROP_GREATER_THAN_OR_EQUAL = 19;
177+
PROP_BEFORE = 20;
178+
PROP_AFTER = 21;
169179
}
170180
string property_name = 1;
171181
CriterionOperator operator = 2;

prefab_cloud_python/config_resolver.py

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,53 @@ def evaluate_criterion(self, criterion, properties):
132132
return self.in_segment(criterion, properties)
133133
if criterion.operator == OPS.NOT_IN_SEG:
134134
return not self.in_segment(criterion, properties)
135-
if criterion.operator == OPS.PROP_ENDS_WITH_ONE_OF:
135+
if criterion.operator in [
136+
OPS.PROP_ENDS_WITH_ONE_OF,
137+
OPS.PROP_DOES_NOT_END_WITH_ONE_OF,
138+
]:
139+
negative = criterion.operator == OPS.PROP_DOES_NOT_END_WITH_ONE_OF
136140
if value_from_properties is None:
137-
return False
138-
return any(
139-
[
140-
str(value_from_properties).endswith(ending)
141-
for ending in criterion.value_to_match.string_list.values
142-
]
141+
return self.negate(negative, False)
142+
return self.negate(
143+
negative,
144+
any(
145+
[
146+
str(value_from_properties).endswith(ending)
147+
for ending in criterion.value_to_match.string_list.values
148+
]
149+
),
150+
)
151+
if criterion.operator in [
152+
OPS.PROP_STARTS_WITH_ONE_OF,
153+
OPS.PROP_DOES_NOT_START_WITH_ONE_OF,
154+
]:
155+
negative = criterion.operator == OPS.PROP_DOES_NOT_START_WITH_ONE_OF
156+
if value_from_properties is None:
157+
return self.negate(negative, False)
158+
return self.negate(
159+
negative,
160+
any(
161+
[
162+
str(value_from_properties).startswith(beginning)
163+
for beginning in criterion.value_to_match.string_list.values
164+
]
165+
),
143166
)
144-
if criterion.operator == OPS.PROP_DOES_NOT_END_WITH_ONE_OF:
167+
if criterion.operator in [
168+
OPS.PROP_CONTAINS_ONE_OF,
169+
OPS.PROP_DOES_NOT_CONTAIN_ONE_OF,
170+
]:
171+
negative = criterion.operator == OPS.PROP_DOES_NOT_CONTAIN_ONE_OF
145172
if value_from_properties is None:
146-
return True
147-
return not any(
148-
[
149-
str(value_from_properties).endswith(ending)
150-
for ending in criterion.value_to_match.string_list.values
151-
]
173+
return self.negate(negative, False)
174+
return self.negate(
175+
negative,
176+
any(
177+
[
178+
string in str(value_from_properties)
179+
for string in criterion.value_to_match.string_list.values
180+
]
181+
),
152182
)
153183
if criterion.operator == OPS.HIERARCHICAL_MATCH:
154184
return value_from_properties.startswith(criterion.value_to_match.string)
@@ -158,6 +188,10 @@ def evaluate_criterion(self, criterion, properties):
158188
logger.info(f"Unknown criterion operator {criterion.operator}")
159189
return False
160190

191+
@staticmethod
192+
def negate(negate, value):
193+
return not value if negate else value
194+
161195
def matches(self, criterion, value, properties):
162196
criterion_value_or_values = ConfigValueUnwrapper.deepest_value(
163197
criterion.value_to_match, self.config.key, properties

0 commit comments

Comments
 (0)