123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- ////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2020 Realm Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- ////////////////////////////////////////////////////////////////////////////
- import Realm
- /**
- :nodoc:
- **/
- public extension ObjectiveCSupport {
- // FIXME: remove these and rename convertBson to convert on the next major
- // version bump
- static func convert(object: AnyBSON?) -> RLMBSON? {
- if let converted = object.map(self.convertBson), !(converted is NSNull) {
- return converted
- }
- return nil
- }
- static func convert(object: RLMBSON?) -> AnyBSON? {
- if let object = object {
- let converted = convertBson(object: object)
- if converted == .null {
- return nil
- }
- return converted
- }
- return nil
- }
- static func convert(_ object: Document) -> [String: RLMBSON] {
- object.reduce(into: Dictionary<String, RLMBSON>()) { (result: inout [String: RLMBSON], kvp) in
- result[kvp.key] = kvp.value.map(convertBson) ?? NSNull()
- }
- }
- /// Convert an `AnyBSON` to a `RLMBSON`.
- static func convertBson(object: AnyBSON) -> RLMBSON {
- switch object {
- case .int32(let val):
- return val as NSNumber
- case .int64(let val):
- return val as NSNumber
- case .double(let val):
- return val as NSNumber
- case .string(let val):
- return val as NSString
- case .binary(let val):
- return val as NSData
- case .datetime(let val):
- return val as NSDate
- case .timestamp(let val):
- return val as NSDate
- case .decimal128(let val):
- return val as RLMDecimal128
- case .objectId(let val):
- return val as RLMObjectId
- case .document(let val):
- return convert(val) as NSDictionary
- case .array(let val):
- return val.map { $0.map(convertBson) } as NSArray
- case .maxKey:
- return MaxKey()
- case .minKey:
- return MinKey()
- case .regex(let val):
- return val
- case .bool(let val):
- return val as NSNumber
- case .uuid(let val):
- return val as NSUUID
- case .null:
- return NSNull()
- }
- }
- static func convert(_ object: [String: RLMBSON]) -> Document {
- object.mapValues { convert(object: $0) }
- }
- /// Convert a `RLMBSON` to an `AnyBSON`.
- static func convertBson(object bson: RLMBSON) -> AnyBSON? {
- switch bson.__bsonType {
- case .null:
- return .null
- case .int32:
- guard let val = bson as? NSNumber else {
- return nil
- }
- return .int32(Int32(val.intValue))
- case .int64:
- guard let val = bson as? NSNumber else {
- return nil
- }
- return .int64(Int64(val.int64Value))
- case .bool:
- guard let val = bson as? NSNumber else {
- return nil
- }
- return .bool(val.boolValue)
- case .double:
- guard let val = bson as? NSNumber else {
- return nil
- }
- return .double(val.doubleValue)
- case .string:
- guard let val = bson as? NSString else {
- return nil
- }
- return .string(val as String)
- case .binary:
- guard let val = bson as? NSData else {
- return nil
- }
- return .binary(val as Data)
- case .timestamp:
- guard let val = bson as? NSDate else {
- return nil
- }
- return .timestamp(val as Date)
- case .datetime:
- guard let val = bson as? NSDate else {
- return nil
- }
- return .datetime(val as Date)
- case .objectId:
- guard let val = bson as? RLMObjectId,
- let oid = try? ObjectId(string: val.stringValue) else {
- return nil
- }
- return .objectId(oid)
- case .decimal128:
- guard let val = bson as? RLMDecimal128 else {
- return nil
- }
- return .decimal128(Decimal128(stringLiteral: val.stringValue))
- case .regularExpression:
- guard let val = bson as? NSRegularExpression else {
- return nil
- }
- return .regex(val)
- case .maxKey:
- return .maxKey
- case .minKey:
- return .minKey
- case .document:
- guard let val = bson as? Dictionary<String, RLMBSON> else {
- return nil
- }
- return .document(convert(val))
- case .array:
- guard let val = bson as? Array<RLMBSON?> else {
- return nil
- }
- return .array(val.compactMap {
- if let value = $0 {
- return convertBson(object: value)
- }
- return .null
- }.map { (v: AnyBSON) -> AnyBSON? in v == .null ? nil : v })
- case .UUID:
- guard let val = bson as? NSUUID else {
- return nil
- }
- return .uuid(val as UUID)
- default:
- return nil
- }
- }
- }
|