1# Copyright (c) 2017 DataCore Software Corp. All Rights Reserved.
2#
3#    Licensed under the Apache License, Version 2.0 (the "License"); you may
4#    not use this file except in compliance with the License. You may obtain
5#    a copy of the License at
6#
7#         http://www.apache.org/licenses/LICENSE-2.0
8#
9#    Unless required by applicable law or agreed to in writing, software
10#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12#    License for the specific language governing permissions and limitations
13#    under the License.
14
15"""Utilities and helper functions."""
16
17from oslo_utils import netutils
18import six
19
20
21def build_network_address(host, port):
22    """Combines the specified host name or IP address with the specified port.
23
24    :param host: Host name or IP address in presentation (string) format
25    :param port: Port number
26    :return: The host name or IP address and port combination;
27             IPv6 addresses are enclosed in the square brackets
28    """
29    if netutils.is_valid_ipv6(host):
30        return '[%s]:%s' % (host, port)
31    else:
32        return '%s:%s' % (host, port)
33
34
35def get_first(predicate, source):
36    """Searches for an item that matches the conditions.
37
38    :param predicate: Defines the conditions of the item to search for
39    :param source: Iterable collection of items
40    :return: The first item that matches the conditions defined by the
41             specified predicate, if found; otherwise StopIteration is raised
42    """
43
44    return six.next(item for item in source if predicate(item))
45
46
47def get_first_or_default(predicate, source, default):
48    """Searches for an item that matches the conditions.
49
50    :param predicate: Defines the conditions of the item to search for
51    :param source: Iterable collection of items
52    :param default: Value that is returned if the iterator is exhausted
53    :return: The first item that matches the conditions defined by the
54             specified predicate, if found; otherwise the default value
55    """
56
57    try:
58        return get_first(predicate, source)
59    except StopIteration:
60        return default
61
62
63def get_distinct_by(key, source):
64    """Finds distinct items for the key and returns the result in a list.
65
66    :param key: Function computing a key value for each item
67    :param source: Iterable collection of items
68    :return: The list of distinct by the key value items
69    """
70
71    seen_keys = set()
72    return [item for item in source
73            if key(item) not in seen_keys and not seen_keys.add(key(item))]
74