// 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, UnmodifiableMapMixin { 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 get keys => _NSDictionaryKeyIterable(this); @override Iterable 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 asDart() => _NSDictionaryAdapter(this); } class _NSMutableDictionaryAdapter with MapBase { 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 get keys => _NSDictionaryAdapter(_dictionary).keys; @override Iterable 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 asDart() => _NSMutableDictionaryAdapter(this); } class _NSDictionaryKeyIterable with Iterable { final _NSDictionaryAdapter _adapter; _NSDictionaryKeyIterable(this._adapter); @override int get length => _adapter.length; @override Iterator get iterator => _NSDictionaryKeyIterator(_adapter._dictionary.keyEnumerator().asDart()); @override bool contains(Object? key) => _adapter.containsKey(key); } class _NSDictionaryKeyIterator implements Iterator { final Iterator _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 { final _NSDictionaryAdapter _adapter; _NSDictionaryValueIterable(this._adapter); @override int get length => _adapter.length; @override Iterator get iterator => _adapter._dictionary.objectEnumerator().asDart(); }