Slather logo

Coverage for "ContainerFactoryBox.swift" : 100.00%

(27 of 27 relevant lines covered)

RouteComposer/Classes/Router/Type Erasure/Boxes/ContainerFactoryBox.swift

1
//
2
// RouteComposer
3
// ContainerFactoryBox.swift
4
// https://github.com/ekazaev/route-composer
5
//
6
// Created by Eugene Kazaev in 2018-2022.
7
// Distributed under the MIT license.
8
//
9
// Become a sponsor:
10
// https://github.com/sponsors/ekazaev
11
//
12
13
import Foundation
14
import UIKit
15
16
struct ContainerFactoryBox<F: ContainerFactory>: PreparableAnyFactory, AnyFactoryBox, MainThreadChecking, CustomStringConvertible {
17
18
    typealias FactoryType = F
19
20
    var factory: FactoryType
21
22
    let action: AnyAction
23
24
    var children: [(factory: PostponedIntegrationFactory, context: AnyContext)] = []
76x
25
26
    var isPrepared = false
27
28
    init?(_ factory: FactoryType, action: AnyAction) {
76x
29
        guard !(factory is NilEntity) else {
76x
30
            return nil
15x
31
        }
61x
32
        self.factory = factory
61x
33
        self.action = action
61x
34
    }
61x
35
36
    mutating func scrapeChildren(from factories: [(factory: AnyFactory, context: AnyContext)]) throws -> [(factory: AnyFactory, context: AnyContext)] {
29x
37
        var otherFactories: [(factory: AnyFactory, context: AnyContext)] = []
29x
38
        var isNonEmbeddableFound = false
29x
39
        children = factories.compactMap { child -> (factory: PostponedIntegrationFactory, context: AnyContext)? in
47x
40
            guard !isNonEmbeddableFound, child.factory.action.isEmbeddable(to: FactoryType.ViewController.self) else {
47x
41
                otherFactories.append(child)
12x
42
                isNonEmbeddableFound = true
12x
43
                return nil
12x
44
            }
35x
45
            return (factory: PostponedIntegrationFactory(for: child.factory), context: child.context)
35x
46
        }
47x
47
        return otherFactories
29x
48
    }
29x
49
50
    func build(with context: AnyContext) throws -> UIViewController {
35x
51
        let typedContext: FactoryType.Context = try context.value()
35x
52
        assertIfNotMainThread()
35x
53
        assertIfNotPrepared()
35x
54
        return try factory.build(with: typedContext, integrating: ChildCoordinator(childFactories: children))
35x
55
    }
35x
56
57
}