// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved. import Foundation import SessionUtilitiesKit class MockCaches: CachesType { private var cacheInstances: [Int: MutableCacheType] = [:] // MARK: - Immutable Access public subscript(cache: CacheInfo.Config) -> I { get { MockCaches.getValueSettingIfNull(cache: cache, &cacheInstances) } } public subscript(cache: CacheInfo.Config) -> M? { get { return (cacheInstances[cache.key] as? M) } set { cacheInstances[cache.key] = newValue.map { cache.mutableInstance($0) } } } public func setting(cache: CacheInfo.Config, to value: M?) -> MockCaches { self[cache] = value return self } // MARK: - Mutable Access @discardableResult public func mutate( cache: CacheInfo.Config, _ mutation: (inout M) -> R ) -> R { var value: M = ((cacheInstances[cache.key] as? M) ?? cache.createInstance()) return mutation(&value) } @discardableResult public func mutate( cache: CacheInfo.Config, _ mutation: (inout M) throws -> R ) throws -> R { var value: M = ((cacheInstances[cache.key] as? M) ?? cache.createInstance()) return try mutation(&value) } @discardableResult private static func getValueSettingIfNull( cache: CacheInfo.Config, _ store: inout [Int: MutableCacheType] ) -> I { guard let value: M = (store[cache.key] as? M) else { let value: M = cache.createInstance() let mutableInstance: MutableCacheType = cache.mutableInstance(value) store[cache.key] = mutableInstance return cache.immutableInstance(value) } return cache.immutableInstance(value) } }