Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[ios, macos] Add match expressions support.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-guerra committed Mar 16, 2018
1 parent 449c68e commit 7c8614b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
44 changes: 44 additions & 0 deletions platform/darwin/src/NSExpression+MGLAdditions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ - (NSNumber *)mgl_number {
return nil;
}

- (id)mgl_matchWithOptions:(NSDictionary<NSNumber *, id> *)stops default:(id)minimum {
[NSException raise:NSInvalidArgumentException
format:@"Match expressions lack underlying Objective-C implementations."];
return nil;
}

@end

@implementation NSNumber (MGLExpressionAdditions)
Expand All @@ -225,6 +231,12 @@ - (id)mgl_stepWithMinimum:(id)minimum stops:(NSDictionary<NSNumber *, id> *)stop
return nil;
}

- (id)mgl_matchWithOptions:(NSDictionary<NSNumber *, id> *)stops default:(id)minimum {
[NSException raise:NSInvalidArgumentException
format:@"Match expressions lack underlying Objective-C implementations."];
return nil;
}

- (NSNumber *)mgl_number {
return self;
}
Expand Down Expand Up @@ -475,6 +487,26 @@ + (instancetype)mgl_expressionWithJSONObject:(id)object {
falseExpression = [NSExpression mgl_expressionWithJSONObject:argumentObjects[2]];
}
return [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression];
} else if ([op isEqualToString:@"match"]) {
NSExpression *operand = [NSExpression mgl_expressionWithJSONObject:argumentObjects[0]];
NSArray *matchOptions = [argumentObjects subarrayWithRange:NSMakeRange(1, argumentObjects.count - 1)];
NSExpression *defaultOption;
if (matchOptions.count % 2) {
defaultOption = [NSExpression mgl_expressionWithJSONObject:matchOptions.lastObject];
matchOptions = [matchOptions subarrayWithRange:NSMakeRange(0, matchOptions.count - 1)];
}
NSMutableArray *optionsArray = [NSMutableArray array];
NSEnumerator *optionsEnumerator = matchOptions.objectEnumerator;
while (NSNumber *key = optionsEnumerator.nextObject) {
NSMutableDictionary *option = [NSMutableDictionary dictionaryWithCapacity:1];
NSExpression *valueExpression = optionsEnumerator.nextObject;
option[key] = [NSExpression mgl_expressionWithJSONObject:valueExpression];
[optionsArray addObject:option];
}
NSExpression *optionsExpression = [NSExpression expressionForConstantValue:optionsArray];
return [NSExpression expressionForFunction:operand
selectorName:@"mgl_matchWithOptions:default:"
arguments:@[optionsExpression, defaultOption]];
} else {
[NSException raise:NSInvalidArgumentException
format:@"Expression operator %@ not yet implemented.", op];
Expand Down Expand Up @@ -666,6 +698,18 @@ - (id)mgl_jsonExpressionObject {
}];
[expressionObject addObject:self.operand.mgl_jsonExpressionObject];
return expressionObject;
} else if ([function isEqualToString:@"mgl_matchWithOptions:default:"]) {
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"match", self.operand.mgl_jsonExpressionObject, nil];
NSArray *optionsArray = self.arguments[0].constantValue;
for (NSDictionary<id, NSExpression*> *options in optionsArray) {
for (NSNumber *key in options.allKeys) {
[expressionObject addObject:key];
[expressionObject addObject:[options[key] mgl_jsonExpressionObject]];
}
}

[expressionObject addObject:[self.arguments[1] mgl_jsonExpressionObject]];
return expressionObject;
} else if ([function isEqualToString:@"median:"] ||
[function isEqualToString:@"mode:"] ||
[function isEqualToString:@"stddev:"] ||
Expand Down
17 changes: 17 additions & 0 deletions platform/darwin/test/MGLExpressionTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,23 @@ - (void)testInterpolationExpressionObject {
}
}

- (void)testMatchExpressionObject {
{
NSArray *options = @[@{@1 : MGLConstantExpression(@"one")}, @{@0 : MGLConstantExpression(@"zero")}];
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(2 - 1, 'mgl_matchWithOptions:default:', %@, 'default')", options];
NSArray *jsonExpression = @[@"match", @[@"-", @2, @1], @1, @"one", @0, @"zero", @"default"];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects( [NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
{
NSArray *options = @[@{@1 : MGLConstantExpression(@"one")}];
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(2 * 1, 'mgl_matchWithOptions:default:', %@, 'default')", options];
NSArray *jsonExpression = @[@"match", @[@"*", @2, @1], @1, @"one", @"default"];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects( [NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
}

- (void)testConditionalExpressionObject {
// FIXME: This test crashes because iOS 8 doesn't have `+[NSExpression expressionForConditional:trueExpression:falseExpression:]`.
// https://github.com/mapbox/mapbox-gl-native/issues/11007
Expand Down

0 comments on commit 7c8614b

Please sign in to comment.