Skip to content

Commit

Permalink
DIVKIT- 663 Release 9.0.0
Browse files Browse the repository at this point in the history
Release 9.0.0
  • Loading branch information
robot-divkit committed Oct 3, 2022
1 parent e5b167c commit 6ca6ce2
Show file tree
Hide file tree
Showing 69 changed files with 776 additions and 132 deletions.
1 change: 0 additions & 1 deletion .gitignore

This file was deleted.

19 changes: 19 additions & 0 deletions Core/Base/ArrayExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import Foundation

extension Array where Element: AnyObject {
@inlinable
public func isEqualByReferences(_ rhs: [Element]) -> Bool {
guard count == rhs.count else { return false }

Expand All @@ -16,38 +17,44 @@ extension Array where Element: AnyObject {
}
}

@inlinable
public func == <T: Equatable>(lhs: [T], rhs: [T?]) -> Bool {
let nonOptionalRhs = rhs.compactMap { $0 }
guard nonOptionalRhs.count == rhs.count else { return false }

return lhs == nonOptionalRhs
}

@inlinable
public func == <T: Equatable>(lhs: [T?], rhs: [T]) -> Bool {
let nonOptionalLhs = lhs.compactMap { $0 }
guard nonOptionalLhs.count == lhs.count else { return false }

return rhs == nonOptionalLhs
}

@inlinable
public func reverseIndex<T: Collection>(_ index: T.Index, inCollection collection: T) -> T.Index {
let distanceToIndex = collection.distance(from: collection.startIndex, to: index)
return collection.index(collection.endIndex, offsetBy: -(1 + distanceToIndex))
}

@inlinable
public func += <T: RangeReplaceableCollection>(
collection: inout T, object: T.Element
) {
collection.append(object)
}

extension Collection {
@inlinable
public func firstMatchWithIndex(
_ predicate: @escaping (Element) -> Bool
) -> (Index, Element)? {
zip(indices, self).first { predicate($0.1) }
}

@inlinable
public func floorIndex<T: BinaryFloatingPoint>(
_ index: T
) -> Int where Index == Int {
Expand All @@ -59,6 +66,7 @@ extension Collection {
return clamp(integral, min: startIndex, max: endIndex.advanced(by: -1))
}

@inlinable
public func ceilIndex<T: BinaryFloatingPoint>(
_ index: T
) -> Int where Index == Int {
Expand All @@ -72,6 +80,7 @@ extension Collection {
}

extension MutableCollection where Element: MutableCollection {
@inlinable
public subscript(coords: (Index, Element.Index)) -> Element.Element {
get {
self[coords.0][coords.1]
Expand All @@ -83,6 +92,7 @@ extension MutableCollection where Element: MutableCollection {
}

extension RangeReplaceableCollection where Index == Int {
@inlinable
public func stableSort(isLessOrEqual: (Element, Element) -> Bool) -> Self {
var result = self
var aux: [Element] = []
Expand Down Expand Up @@ -129,6 +139,7 @@ extension NSArray {
}
}

@inlinable
public func == <A: Equatable, B: Equatable>(lhs: [(A, B)], rhs: [(A, B)]) -> Bool {
guard lhs.count == rhs.count else {
return false
Expand All @@ -143,11 +154,13 @@ public func == <A: Equatable, B: Equatable>(lhs: [(A, B)], rhs: [(A, B)]) -> Boo
return true
}

@inlinable
public func != <A: Equatable, B: Equatable>(lhs: [(A, B)], rhs: [(A, B)]) -> Bool {
!(lhs == rhs)
}

extension Collection where Element: Equatable {
@inlinable
public func element(after item: Element) -> Element? {
guard let itemIndex = firstIndex(of: item) else {
return nil
Expand All @@ -166,11 +179,13 @@ extension RandomAccessCollection {
}
}

@inlinable
public func arraysEqual<T>(_ lhs: [T], _ rhs: [T], equalityTest: (T, T) -> Bool) -> Bool {
guard lhs.count == rhs.count else { return false }
return zip(lhs, rhs).first { equalityTest($0.0, $0.1) == false } == nil ? true : false
}

@inlinable
public func == <A: Equatable, B: Equatable, C: Equatable>(
_ lhs: [(A, B, C)],
_ rhs: [(A, B, C)]
Expand All @@ -179,6 +194,7 @@ public func == <A: Equatable, B: Equatable, C: Equatable>(
}

extension Array {
@inlinable
public func iterativeFlatMap<T>(_ transform: (Element, Index) throws -> T?) rethrows -> [T] {
var result = [T]()
result.reserveCapacity(count)
Expand All @@ -190,6 +206,7 @@ extension Array {
return result
}

@inlinable
public func toDictionary<K, V>() -> [K: V] where Element == (K, V?) {
var dict = [K: V]()
forEach { key, value in
Expand All @@ -198,13 +215,15 @@ extension Array {
return dict
}

@inlinable
public var randomElement: Element? {
guard !isEmpty else { return nil }
return self[Int(arc4random_uniform(UInt32(count)))]
}
}

extension Array where Element: Hashable {
@inlinable
public var uniqueElements: [Element] {
Array(Set(self))
}
Expand Down
1 change: 1 addition & 0 deletions Core/Base/AutodisposePool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extension Sequence where Element == Disposable {
}

extension AutodisposePool {
@inlinable
@discardableResult
public func retain<T>(_ value: T) -> T {
add(Disposable { withExtendedLifetime(value) {} })
Expand Down
4 changes: 4 additions & 0 deletions Core/Base/Combine.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
// Copyright 2020 Yandex LLC. All rights reserved.

public enum Combine {
@inlinable
public static func `throw`<T>(_ first: T, last: T) throws -> T {
throw CombineFailure(values: [first, last])
}

@inlinable
public static func lastWithAssertionFailure<T>(_ first: T, last: T) -> T {
assertionFailure(CombineFailure(values: [first, last]).debugDescription)
return last
}
}

public struct CombineFailure<T>: Error, CustomDebugStringConvertible {
@usableFromInline
let values: [T]

@inlinable
public init(values: [T]) {
self.values = values
}
Expand Down
2 changes: 2 additions & 0 deletions Core/Base/DeferredValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extension DeferredValue {
return makeReadySignal(notifyOnAdd: true, transform: { $0 })
}

@inlinable
public func asObservableVariable<U>(fallbackUntilLoaded: U) -> T
where T == ObservableVariable<U> {
currentValue ?? observableCurrentValue.flatMap { $0 ?? .constant(fallbackUntilLoaded) }
Expand All @@ -44,6 +45,7 @@ extension DeferredValue {
asObservableVariable(fallbackUntilLoaded: false)
}

@inlinable
public func asSignal<U>() -> T where T == Signal<U> {
currentValue ?? readySignal.flatMap { $0 }
}
Expand Down
31 changes: 31 additions & 0 deletions Core/Base/DictionaryExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ extension NSDictionary {
}

extension Dictionary {
@inlinable
public init<K: Sequence, E: Sequence>(_ keys: K, _ values: E) where K.Element == Key,
E.Element == Value {
self.init(zip(keys, values), uniquingKeysWith: { $1 })
}

@inlinable
public func valuesForKeysMatching(_ includeKey: (Key) -> Bool) -> [Value] {
compactMap { includeKey($0.0) ? $0.1 : nil }
}
Expand All @@ -26,15 +28,30 @@ extension Dictionary {
try? JSONSerialization.data(withJSONObject: self, options: [])
}

@inlinable
public func value(forCaseInsensitiveKey key: Key) -> Value? {
guard let lowercasedKey = (key as? String)?.lowercased() else { return nil }
return first(where: { ($0.key as? String)?.lowercased() == lowercasedKey })?.value
}

@inlinable
public func transformed<T>(_ transform: (Value) throws -> T) rethrows -> [Key: T] {
[Key: T](try map { ($0.key, try transform($0.value)) }, uniquingKeysWith: { $1 })
}

@inlinable
public func map<ResultKey, ResultValue>(
key keyMapper: (Key) throws -> ResultKey,
value valueMapper: (Value) throws -> ResultValue
) rethrows -> [ResultKey: ResultValue] {
var result = [:] as [ResultKey: ResultValue]
for (key, value) in self {
result[try keyMapper(key)] = try valueMapper(value)
}
return result
}

@inlinable
public func filteringNilValues<T>() -> [Key: T] where Value == T? {
[Key: T](
compactMap {
Expand All @@ -49,6 +66,7 @@ extension Dictionary {
)
}

@inlinable
public func mergingRecursively(_ other: [Key: Value]) -> [Key: Value] {
var result = self
for (key, otherValue) in other {
Expand All @@ -65,17 +83,30 @@ extension Dictionary {
}
return result
}

@inlinable
public mutating func getOrCreate(_ key: Key, factory: () -> Value) -> Value {
if let value = self[key] {
return value
}
let value = factory()
self[key] = value
return value
}
}

@inlinable
public func + <K, V>(lhs: [K: V], rhs: [K: V]) -> [K: V] {
lhs.merging(rhs, uniquingKeysWith: { $1 })
}

@inlinable
public func += <K, V>(lhs: inout [K: V], rhs: [K: V]) {
lhs.merge(rhs, uniquingKeysWith: { $1 })
}

extension Dictionary where Key == String {
@inlinable
public var lowercasedKeys: [Key: Value] {
var result: [String: Value] = [:]
for key in keys {
Expand Down
1 change: 1 addition & 0 deletions Core/Base/Disposable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public final class Disposable {
}

extension Disposable {
@inlinable
public convenience init<S: Sequence>(_ disposables: S) where S.Element == Disposable {
self.init {
for disposable in disposables {
Expand Down
2 changes: 2 additions & 0 deletions Core/Base/Either.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public enum Either<T, U> {
case left(T)
case right(U)

@inlinable
public func mapLeft<T1>(_ transform: (T) throws -> T1) rethrows -> Either<T1, U> {
switch self {
case let .left(t):
Expand All @@ -15,6 +16,7 @@ public enum Either<T, U> {
}
}

@inlinable
public func mapRight<U1>(_ transform: (U) throws -> U1) rethrows -> Either<T, U1> {
switch self {
case let .left(t):
Expand Down
1 change: 1 addition & 0 deletions Core/Base/Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public func asyncActionAssertCompletionOnMT(
}
}

@inlinable
public func partialApply<T, U>(_ f: @escaping (T) -> U, with arg: T) -> () -> U {
{ f(arg) }
}
26 changes: 26 additions & 0 deletions Core/Base/GCD.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,31 @@ public func onMainThread(_ block: @escaping () -> Void) {
}
}

public func onMainThreadResult<T>(_ function: @escaping () -> T) -> Future<T> {
let (future, feed) = Future<T>.create()
onMainThread {
feed(function())
}
return future
}

public func onMainThreadResult<T>(_ function: @escaping () -> Future<T>) -> Future<T> {
let (future, feed) = Future<T>.create()
onMainThread {
function().resolved { result in
onMainThread {
feed(result)
}
}
}
return future
}

public func onMainThreadAsync(_ block: @escaping () -> Void) {
DispatchQueue.main.async(execute: block)
}

@inlinable
public func onMainThreadSync<T>(_ block: () -> T) -> T {
if Thread.isMainThread {
return block()
Expand All @@ -44,6 +65,10 @@ public func onBackgroundThread(qos: DispatchQoS.QoSClass) -> (@escaping () -> Vo
}
}

public func invokeImmediately(_ block: @escaping () -> Void) {
block()
}

@discardableResult
public func dispatchAfter(
_ delay: TimeInterval,
Expand All @@ -68,6 +93,7 @@ public func after(
return workItem
}

@inlinable
public func performAsyncAction<T>(
_ action: (@escaping (T) -> Void) -> Void,
withMinimumDelay minimumDelay: TimeInterval,
Expand Down
6 changes: 6 additions & 0 deletions Core/Base/Lazy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public final class Lazy<T> {
private let shouldAssertOnMainThread: Bool
private var state: State

@inlinable
public subscript<U>(dynamicMember path: KeyPath<T, U>) -> Lazy<U> {
map { $0[keyPath: path] }
}
Expand Down Expand Up @@ -63,6 +64,11 @@ public final class Lazy<T> {
self.init({ value }, shouldAssertOnMainThread: false)
}

public init(loaded value: T) {
self.state = .loaded(value: value)
shouldAssertOnMainThread = false
}

public func whenLoaded(perform action: @escaping Action) {
ensureIsValidThread()
switch state {
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions Core/Base/NonEmpty+Array.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
public typealias NonEmptyArray<Element> = NonEmpty<[Element]>

extension NonEmpty {
@inlinable
public init?<E>(_ array: C) where C == [E] {
guard let head = array.first else {
return nil
}
self.init(head, Array(array.dropFirst()))
}

@inlinable
public func asArray() -> [C.Element] {
Array(self)
}
Expand Down
Loading

0 comments on commit 6ca6ce2

Please sign in to comment.