blob: aad8021637595e502dc3c5b9373baa3dbeedae90 [file] [log] [blame]
// 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 'dart:collection';
import 'package:collection/collection.dart';
import 'converter.dart';
import 'internal.dart';
import 'ns_enumerator.dart';
import 'objective_c_bindings_generated.dart';
class _NSDictionaryAdapter
with
MapBase<NSCopying, ObjCObject>,
UnmodifiableMapMixin<NSCopying, ObjCObject> {
final NSDictionary _dictionary;
_NSDictionaryAdapter(this._dictionary);
@override
int get length => _dictionary.count;
@override
ObjCObject? operator [](Object? key) =>
key is NSCopying ? _dictionary.objectForKey(key) : null;
@override
Iterable<NSCopying> get keys => _NSDictionaryKeyIterable(this);
@override
Iterable<ObjCObject> get values => _NSDictionaryValueIterable(this);
@override
bool containsKey(Object? key) => this[key] != null;
}
extension NSDictionaryToAdapter on NSDictionary {
/// Wraps this [NSDictionary] in an adapter that implements an immutable
/// [Map].
///
/// This is not a conversion, doesn't create a new map, or change the
/// elements. For deep conversion, use [toDartMap].
Map<NSCopying, ObjCObject> asDart() => _NSDictionaryAdapter(this);
}
class _NSMutableDictionaryAdapter with MapBase<NSCopying, ObjCObject> {
final NSMutableDictionary _dictionary;
_NSMutableDictionaryAdapter(this._dictionary);
@override
int get length => _dictionary.count;
@override
ObjCObject? operator [](Object? key) =>
key is NSCopying ? _dictionary.objectForKey(key) : null;
@override
void operator []=(NSCopying key, ObjCObject value) =>
NSMutableDictionary$Methods(
_dictionary,
).setObject(value, forKey: NSCopying.as(key));
@override
Iterable<NSCopying> get keys => _NSDictionaryAdapter(_dictionary).keys;
@override
Iterable<ObjCObject> get values => _NSDictionaryAdapter(_dictionary).values;
@override
bool containsKey(Object? key) => this[key] != null;
@override
void clear() => _dictionary.removeAllObjects();
@override
ObjCObject? remove(Object? key) {
if (key is! NSCopying) return null;
final old = this[key];
_dictionary.removeObjectForKey(key);
return old;
}
}
extension NSMutableDictionaryToAdapter on NSMutableDictionary {
/// Wraps this [NSMutableDictionary] in an adapter that implements [Map].
///
/// This is not a conversion, doesn't create a new map, or change the
/// elements. For deep conversion, use [toDartMap].
Map<NSCopying, ObjCObject> asDart() => _NSMutableDictionaryAdapter(this);
}
class _NSDictionaryKeyIterable with Iterable<NSCopying> {
final _NSDictionaryAdapter _adapter;
_NSDictionaryKeyIterable(this._adapter);
@override
int get length => _adapter.length;
@override
Iterator<NSCopying> get iterator =>
_NSDictionaryKeyIterator(_adapter._dictionary.keyEnumerator().asDart());
@override
bool contains(Object? key) => _adapter.containsKey(key);
}
class _NSDictionaryKeyIterator implements Iterator<NSCopying> {
final Iterator<ObjCObject> _iterator;
_NSDictionaryKeyIterator(this._iterator);
@override
NSCopying get current => NSCopying.as(_iterator.current);
@override
@pragma('vm:prefer-inline')
bool moveNext() => _iterator.moveNext();
}
class _NSDictionaryValueIterable with Iterable<ObjCObject> {
final _NSDictionaryAdapter _adapter;
_NSDictionaryValueIterable(this._adapter);
@override
int get length => _adapter.length;
@override
Iterator<ObjCObject> get iterator =>
_adapter._dictionary.objectEnumerator().asDart();
}