blob: e96e7474e3a05033a79643cbd51530d72148ee70 [file] [log] [blame]
Jens Geyer56e5b9b2015-10-09 22:01:55 +02001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20import Foundation
21
22
23public struct TMap<Key : TSerializable, Value : TSerializable> : CollectionType, DictionaryLiteralConvertible, TSerializable {
24
25 public static var thriftType : TType { return .MAP }
26
27 typealias Storage = Dictionary<Key, Value>
28
29 public typealias Index = Storage.Index
30
31 public typealias Element = Storage.Element
32
33 private var storage : Storage
34
35 public var startIndex : Index {
36 return storage.startIndex
37 }
38
39 public var endIndex: Index {
40 return storage.endIndex
41 }
42
43 public var keys: LazyMapCollection<[Key : Value], Key> {
44 return storage.keys
45 }
46
47 public var values: LazyMapCollection<[Key : Value], Value> {
48 return storage.values
49 }
50
51 public init() {
52 storage = Storage()
53 }
54
55 public init(dictionaryLiteral elements: (Key, Value)...) {
56 storage = Storage()
57 for (key, value) in elements {
58 storage[key] = value
59 }
60 }
61
62 public init(minimumCapacity: Int) {
63 storage = Storage(minimumCapacity: minimumCapacity)
64 }
65
66 public subscript (position: Index) -> Element {
67 get {
68 return storage[position]
69 }
70 }
71
72 public func indexForKey(key: Key) -> Index? {
73 return storage.indexForKey(key)
74 }
75
76 public subscript (key: Key) -> Value? {
77 get {
78 return storage[key]
79 }
80 set {
81 storage[key] = newValue
82 }
83 }
84
85 public mutating func updateValue(value: Value, forKey key: Key) -> Value? {
86 return updateValue(value, forKey: key)
87 }
88
89 public mutating func removeAtIndex(index: DictionaryIndex<Key, Value>) -> (Key, Value) {
90 return removeAtIndex(index)
91 }
92
93 public mutating func removeValueForKey(key: Key) -> Value? {
94 return storage.removeValueForKey(key)
95 }
96
97 public mutating func removeAll(keepCapacity keepCapacity: Bool = false) {
98 storage.removeAll(keepCapacity: keepCapacity)
99 }
100
101 public var hashValue : Int {
102 let prime = 31
103 var result = 1
104 for (key, value) in storage {
105 result = prime * result + key.hashValue
106 result = prime * result + value.hashValue
107 }
108 return result
109 }
110
111 public static func readValueFromProtocol(proto: TProtocol) throws -> TMap {
112 let (keyType, valueType, size) = try proto.readMapBegin()
113 if keyType != Key.thriftType || valueType != Value.thriftType {
114 throw NSError(
115 domain: TProtocolErrorDomain,
116 code: Int(TProtocolError.InvalidData.rawValue),
117 userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: TProtocolExtendedError.UnexpectedType.rawValue)])
118 }
119 var map = TMap()
120 for _ in 0..<size {
121 let key = try Key.readValueFromProtocol(proto)
122 let value = try Value.readValueFromProtocol(proto)
123 map.storage[key] = value
124 }
125 try proto.readMapEnd()
126 return map
127 }
128
129 public static func writeValue(value: TMap, toProtocol proto: TProtocol) throws {
130 try proto.writeMapBeginWithKeyType(Key.thriftType, valueType: Value.thriftType, size: value.count)
131 for (key, value) in value.storage {
132 try Key.writeValue(key, toProtocol: proto)
133 try Value.writeValue(value, toProtocol: proto)
134 }
135 try proto.writeMapEnd()
136 }
137
138}
139
140
141extension TMap : CustomStringConvertible, CustomDebugStringConvertible {
142
143 public var description : String {
144 return storage.description
145 }
146
147 public var debugDescription : String {
148 return storage.debugDescription
149 }
150
151}
152
153public func ==<Key, Value>(lhs: TMap<Key,Value>, rhs: TMap<Key, Value>) -> Bool {
154 if lhs.count != rhs.count {
155 return false
156 }
157 return lhs.storage == rhs.storage
158}