blob: 9c7b353f78991d653d0371ad9ef233176a1d2fdd [file] [log] [blame] [edit]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'internal.dart';
import 'ns_date.dart';
import 'ns_number.dart';
import 'ns_string.dart';
import 'objective_c_bindings_generated.dart';
ObjCObjectBase _defaultObjCConverter(Object o) =>
throw UnimplementedError('No conversion for $o');
/// Converts a Dart object to the corresponding Objective C object.
///
/// This supports basic types like `num` and `String`. It also works on
/// collections, and recursively converts their elements.
///
/// If [dartObject] is not one of the recognized types, [convertOther] is
/// called. If [convertOther] is not provided, an error is thrown.
ObjCObjectBase toObjCObject(
Object? dartObject, {
ObjCObjectBase Function(Object) convertOther = _defaultObjCConverter,
}) => switch (dartObject) {
null => NSNull.null$(),
ObjCObjectBase() => dartObject,
num() => dartObject.toNSNumber(),
String() => dartObject.toNSString(),
DateTime() => dartObject.toNSDate(),
List<Object>() => dartObject.toNSArray(convertOther: convertOther),
Set<Object>() => dartObject.toNSSet(convertOther: convertOther),
Map<Object, Object>() => dartObject.toNSDictionary(
convertOther: convertOther,
),
_ => convertOther(dartObject),
};
extension DartListToNSArray on List<Object> {
NSArray toNSArray({
ObjCObjectBase Function(Object) convertOther = _defaultObjCConverter,
}) => NSArray.of(map((o) => toObjCObject(o, convertOther: convertOther)));
}
extension DartSetToNSSet on Set<Object> {
NSSet toNSSet({
ObjCObjectBase Function(Object) convertOther = _defaultObjCConverter,
}) => NSSet.of(map((o) => toObjCObject(o, convertOther: convertOther)));
}
extension DartMapToNSDictionary on Map<Object, Object> {
NSDictionary toNSDictionary({
ObjCObjectBase Function(Object) convertOther = _defaultObjCConverter,
}) => NSDictionary.fromEntries(
entries.map(
(kv) => MapEntry(
toObjCObject(kv.key, convertOther: convertOther) as NSCopying,
toObjCObject(kv.value, convertOther: convertOther),
),
),
);
}
Object _defaultDartConverter(ObjCObjectBase o) => o;
/// Converts a Objective C object to the corresponding Dart object.
///
/// This supports basic types like `NSNumber` and `NSString`. It also works on
/// collections, and recursively converts their elements.
///
/// If [objCObject] is not one of the recognized types, [convertOther] is
/// called. If [convertOther] is not provided, [objCObject] is returned
/// directly.
Object toDartObject(
ObjCObjectBase objCObject, {
Object Function(ObjCObjectBase) convertOther = _defaultDartConverter,
}) {
// A type-based switch, like in toObjCObject, won't work here because the
// object could have a Dart runtime type of eg NSObject, even if the
// underlying ObjC object that the Dart object is wrapping is a NSNumber.
if (NSNumber.isInstance(objCObject)) {
return NSNumber.castFrom(objCObject).numValue;
}
if (NSString.isInstance(objCObject)) {
return NSString.castFrom(objCObject).toDartString();
}
if (NSDate.isInstance(objCObject)) {
return NSDate.castFrom(objCObject).toDateTime();
}
if (NSArray.isInstance(objCObject)) {
return NSArray.castFrom(objCObject).toDartList(convertOther: convertOther);
}
if (NSSet.isInstance(objCObject)) {
return NSSet.castFrom(objCObject).toDartSet(convertOther: convertOther);
}
if (NSDictionary.isInstance(objCObject)) {
return NSDictionary.castFrom(
objCObject,
).toDartMap(convertOther: convertOther);
}
return convertOther(objCObject);
}
/// Converts a Objective C object to the corresponding Dart object.
///
/// See [toDartObject]. This method will additionally return `null` if passed an
/// `NSNull`.
Object? toNullableDartObject(
ObjCObjectBase objCObject, {
Object Function(ObjCObjectBase) convertOther = _defaultDartConverter,
}) {
if (NSNull.isInstance(objCObject)) {
return null;
}
return toDartObject(objCObject, convertOther: convertOther);
}
extension NSArrayToDartList on NSArray {
List<Object> toDartList({
Object Function(ObjCObjectBase) convertOther = _defaultDartConverter,
}) => map((o) => toDartObject(o, convertOther: convertOther)).toList();
}
extension NSSetToDartSet on NSSet {
Set<Object> toDartSet({
Object Function(ObjCObjectBase) convertOther = _defaultDartConverter,
}) => map((o) => toDartObject(o, convertOther: convertOther)).toSet();
}
extension NSDictionaryToDartMap on NSDictionary {
Map<Object, Object> toDartMap({
Object Function(ObjCObjectBase) convertOther = _defaultDartConverter,
}) => Map.fromEntries(
entries.map(
(kv) => MapEntry(
toDartObject(kv.key, convertOther: convertOther),
toDartObject(kv.value, convertOther: convertOther),
),
),
);
}