summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm14
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm9
-rw-r--r--platform/darwin/src/NSPredicate+MGLAdditions.mm60
3 files changed, 58 insertions, 25 deletions
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
index 15aa71419d..af9216f9ce 100644
--- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
@@ -140,10 +140,18 @@
[NSException raise:NSInvalidArgumentException
format:@"NSPredicateOperatorType:%lu is not supported.", (unsigned long)self.predicateOperatorType];
}
- if (op) {
- return @[op, self.leftExpression.mgl_jsonExpressionObject, self.rightExpression.mgl_jsonExpressionObject];
+ if (!op) {
+ return nil;
}
- return nil;
+ NSArray *comparisonArray = @[op, self.leftExpression.mgl_jsonExpressionObject, self.rightExpression.mgl_jsonExpressionObject];
+ if (self.options) {
+ NSDictionary *collatorObject = @{
+ @"case-sensitive": @(!(self.options & NSCaseInsensitivePredicateOption)),
+ @"diacritic-sensitive": @(!(self.options & NSDiacriticInsensitivePredicateOption)),
+ };
+ return [comparisonArray arrayByAddingObject:@[@"collator", collatorObject]];
+ }
+ return comparisonArray;
}
@end
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 653e3d67e6..d03d7dbaec 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -784,6 +784,9 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
return [NSExpression expressionForFunction:functionName
arguments:subexpressions];
+ } else if ([op isEqualToString:@"collator"]) {
+ // Avoid wrapping collator options object in literal expression.
+ return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:array];
} else if ([op isEqualToString:@"literal"]) {
if ([argumentObjects.firstObject isKindOfClass:[NSArray class]]) {
return [NSExpression expressionForAggregate:MGLSubexpressionsWithJSONObjects(argumentObjects.firstObject)];
@@ -1208,6 +1211,12 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
[NSException raise:NSInvalidArgumentException
format:@"Casting expression to %@ not yet implemented.", type];
} else if ([function isEqualToString:@"MGL_FUNCTION"]) {
+ NSExpression *op = self.arguments.firstObject;
+ if (op.expressionType == NSConstantValueExpressionType
+ && [op.constantValue isEqualToString:@"collator"]) {
+ // Avoid wrapping collator options object in literal expression.
+ return @[@"collator", self.arguments[1].constantValue];
+ }
return self.arguments.mgl_jsonExpressionObject;
} else if (op == [MGLColor class] && [function isEqualToString:@"colorWithRed:green:blue:alpha:"]) {
NSArray *arguments = self.arguments.mgl_jsonExpressionObject;
diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm
index 4b9a4177cb..d01b2c8f83 100644
--- a/platform/darwin/src/NSPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSPredicate+MGLAdditions.mm
@@ -46,6 +46,15 @@ NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) {
return subpredicates;
}
+static NSDictionary * const MGLPredicateOperatorTypesByJSONOperator = @{
+ @"==": @(NSEqualToPredicateOperatorType),
+ @"!=": @(NSNotEqualToPredicateOperatorType),
+ @"<": @(NSLessThanPredicateOperatorType),
+ @"<=": @(NSLessThanOrEqualToPredicateOperatorType),
+ @">": @(NSGreaterThanPredicateOperatorType),
+ @">=": @(NSGreaterThanOrEqualToPredicateOperatorType),
+};
+
+ (instancetype)predicateWithMGLJSONObject:(id)object {
if ([object isEqual:@YES]) {
return [NSPredicate predicateWithValue:YES];
@@ -58,30 +67,37 @@ NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) {
NSArray *objects = (NSArray *)object;
NSString *op = objects.firstObject;
- if ([op isEqualToString:@"=="]) {
- NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ == %@" argumentArray:subexpressions];
- }
- if ([op isEqualToString:@"!="]) {
- NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ != %@" argumentArray:subexpressions];
- }
- if ([op isEqualToString:@"<"]) {
- NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ < %@" argumentArray:subexpressions];
- }
- if ([op isEqualToString:@"<="]) {
- NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ <= %@" argumentArray:subexpressions];
- }
- if ([op isEqualToString:@">"]) {
- NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ > %@" argumentArray:subexpressions];
- }
- if ([op isEqualToString:@">="]) {
+ NSNumber *operatorTypeNumber = MGLPredicateOperatorTypesByJSONOperator[op];
+ if (operatorTypeNumber) {
+ NSPredicateOperatorType operatorType = (NSPredicateOperatorType)[operatorTypeNumber unsignedIntegerValue];
+
+ NSComparisonPredicateOptions options = 0;
+ if (objects.count > 3) {
+ NSArray *collatorExpression = objects[3];
+ NSCAssert([collatorExpression isKindOfClass:[NSArray class]], @"Collators must be dictionaries.");
+ NSCAssert(collatorExpression.count == 2, @"Malformed collator expression");
+ NSDictionary *collator = collatorExpression[1];
+ NSCAssert([collator isKindOfClass:[NSDictionary class]], @"Malformed collator in collator expression");
+
+ // Predicate options can’t express specific locales as collators can.
+ if (!collator[@"locale"]) {
+ if ([(collator[@"case-sensitive"] ?: @YES) isEqual:@NO]) {
+ options |= NSCaseInsensitivePredicateOption;
+ }
+ if ([(collator[@"diacritic-sensitive"] ?: @YES) isEqual:@NO]) {
+ options |= NSDiacriticInsensitivePredicateOption;
+ }
+ }
+ }
+
NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ >= %@" argumentArray:subexpressions];
+ return [NSComparisonPredicate predicateWithLeftExpression:subexpressions[0]
+ rightExpression:subexpressions[1]
+ modifier:NSDirectPredicateModifier
+ type:operatorType
+ options:options];
}
+
if ([op isEqualToString:@"!"]) {
NSArray *subpredicates = MGLSubpredicatesWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
if (subpredicates.count > 1) {