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

[ios, macos] Write "collator" wrappers for NSExpression #12269

Closed
ChrisLoer opened this issue Jun 29, 2018 · 4 comments
Closed

[ios, macos] Write "collator" wrappers for NSExpression #12269

ChrisLoer opened this issue Jun 29, 2018 · 4 comments
Assignees
Labels
iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS runtime styling

Comments

@ChrisLoer
Copy link
Contributor

Follow-on for #11869: ios/macos now support "collator" expressions, but they're not directly exposed via the SDK. Collator expressions take a dictionary-style object as an argument, e.g.:

["collator", {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"}]

This is a new pattern so we'll have to figure out the right iOS/macOS way to expose it.

/cc @1ec5 @friedbunny @julianrex

@1ec5
Copy link
Contributor

1ec5 commented Jun 30, 2018

There are a few pieces to implement here:

@1ec5 1ec5 added iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS runtime styling labels Jun 30, 2018
@ChrisLoer
Copy link
Contributor Author

If collator can be used on its own, independently of a comparison expression, then we need to make sure it can be represented and round-tripped somehow – even if it’s just a struct in the NSPredicate syntax. But I think the modifiers would be the focus of our iOS/macOS support for collators, since it’s much more concise than what we could implement for standalone collators.

I'm not sure of all the terminology here, but currently a Collator (the result of evaluating a CollatorExpression) can be passed into comparison operators and it can also be passed as an argument to resolved-locale. It's not a valid result from an expression (e.g. there's no converter from Collator to mbgl::Value). cc @anandthakker

@1ec5
Copy link
Contributor

1ec5 commented Jun 30, 2018

OK, that makes sense. So the most common way to perform a case-insensitive, locale-sensitive comparison in Objective-C or Swift would be:

NSPredicate(format: "name_fr =[cl] 'quebec'")

Note how l means “current locale”; there isn’t a way to specify a specific locale using this syntax.

As it is, it’s already possible, if ugly, to create a collator expression manually like this:

NSPredicate(format: "MGL_FUNCTION('==', name_fr, 'quebec', MGL_FUNCTION('collator', %@))",
            ["case-sensitive": false, "diacritic-sensitive": true, "locale": "en"])

So far we’ve only defined aftermarket expression functions for the most common operators, but we could define one for creating a collator, with a syntax like this:

NSPredicate(format: "MGL_FUNCTION('==', name_fr, 'quebec',
                                  collatorCaseInsensitive:diacriticInsensitive:locale:(TRUE, FALSE, 'en'))")

But more likely, we’d have operators like == convert a dictionary in the third argument to a collator:

NSPredicate(format: "MGL_FUNCTION('==', name_fr, 'quebec', %@)",
            ["case-sensitive": false, "diacritic-sensitive": true, "locale": "en"])

If we encounter a collator expression in style JSON, we should be able to convert it to a native comparison in some cases, but if the collator specifies a locale, then we’d only be able to use the NSPredicate syntax if the locale happens to match the current locale. Otherwise, we’d have to use the more verbose syntax.

@1ec5
Copy link
Contributor

1ec5 commented Jul 5, 2018

The […] flags in NSPredicate are represented by NSComparisonPredicate.options.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS runtime styling
Projects
None yet
Development

No branches or pull requests

2 participants