]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/tokenizer/icu_variants.py
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / nominatim / tokenizer / icu_variants.py
1 """
2 Data structures for saving variant expansions for ICU tokenizer.
3 """
4 from collections import namedtuple
5 import json
6
7 _ICU_VARIANT_PORPERTY_FIELDS = ['lang']
8
9
10 class ICUVariantProperties(namedtuple('_ICUVariantProperties', _ICU_VARIANT_PORPERTY_FIELDS)):
11     """ Data container for saving properties that describe when a variant
12         should be applied.
13
14         Property instances are hashable.
15     """
16     @classmethod
17     def from_rules(cls, _):
18         """ Create a new property type from a generic dictionary.
19
20             The function only takes into account the properties that are
21             understood presently and ignores all others.
22         """
23         return cls(lang=None)
24
25
26 ICUVariant = namedtuple('ICUVariant', ['source', 'replacement', 'properties'])
27
28
29 def pickle_variant_set(variants):
30     """ Serializes an iterable of variant rules to a string.
31     """
32     # Create a list of property sets. So they don't need to be duplicated
33     properties = {}
34     pid = 1
35     for variant in variants:
36         if variant.properties not in properties:
37             properties[variant.properties] = pid
38             pid += 1
39
40     # Convert the variants into a simple list.
41     variants = [(v.source, v.replacement, properties[v.properties]) for v in variants]
42
43     # Convert everythin to json.
44     return json.dumps({'properties': {v: k._asdict() for k, v in properties.items()},
45                        'variants': variants})
46
47
48 def unpickle_variant_set(variant_string):
49     """ Deserializes a variant string that was previously created with
50         pickle_variant_set() into a set of ICUVariants.
51     """
52     data = json.loads(variant_string)
53
54     properties = {int(k): ICUVariantProperties.from_rules(v)
55                   for k, v in data['properties'].items()}
56
57     return set((ICUVariant(src, repl, properties[pid]) for src, repl, pid in data['variants']))