Slather logo

Coverage for "GeneralStep.swift" : 100.00%

(36 of 36 relevant lines covered)

RouteComposer/Classes/Steps/GeneralStep.swift

1
//
2
// RouteComposer
3
// GeneralStep.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
/// A wrapper for the general steps that can be applied to any `UIViewController`
17
public enum GeneralStep {
18
19
    // MARK: Internal entities
20
21
    struct RootViewControllerStep: RoutingStep, PerformableStep {
22
23
        let windowProvider: WindowProvider
24
25
        /// Constructor
26
        init(windowProvider: WindowProvider = RouteComposerDefaults.shared.windowProvider) {
71x
27
            self.windowProvider = windowProvider
71x
28
        }
71x
29
30
        func perform(with context: AnyContext) throws -> PerformableStepResult {
25x
31
            guard let viewController = windowProvider.window?.rootViewController else {
25x
32
                throw RoutingError.compositionFailed(.init("Root view controller was not found."))
1x
33
            }
24x
34
            return .success(viewController)
24x
35
        }
25x
36
37
    }
38
39
    struct CurrentViewControllerStep: RoutingStep, PerformableStep {
40
41
        let windowProvider: WindowProvider
42
43
        /// Constructor
44
        init(windowProvider: WindowProvider = RouteComposerDefaults.shared.windowProvider) {
38x
45
            self.windowProvider = windowProvider
38x
46
        }
38x
47
48
        func perform(with context: AnyContext) throws -> PerformableStepResult {
18x
49
            guard let viewController = windowProvider.window?.topmostViewController else {
18x
50
                throw RoutingError.compositionFailed(.init("Topmost view controller was not found."))
1x
51
            }
17x
52
            return .success(viewController)
17x
53
        }
18x
54
55
    }
56
57
    struct FinderStep: RoutingStep, PerformableStep {
58
59
        let finder: AnyFinder?
60
61
        init(finder: some Finder) {
16x
62
            self.finder = FinderBox(finder)
16x
63
        }
16x
64
65
        func perform(with context: AnyContext) throws -> PerformableStepResult {
18x
66
            guard let viewController = try finder?.findViewController(with: context) else {
18x
67
                throw RoutingError.compositionFailed(.init("A view controller of \(String(describing: finder)) was not found."))
6x
68
            }
12x
69
            return .success(viewController)
12x
70
        }
18x
71
    }
72
73
    // MARK: Steps
74
75
    /// Returns the root view controller of the key window.
76
    public static func root<C>(windowProvider: WindowProvider = RouteComposerDefaults.shared.windowProvider) -> DestinationStep<UIViewController, C> {
70x
77
        DestinationStep(RootViewControllerStep(windowProvider: windowProvider))
70x
78
    }
70x
79
80
    /// Returns the topmost presented view controller.
81
    public static func current<C>(windowProvider: WindowProvider = RouteComposerDefaults.shared.windowProvider) -> DestinationStep<UIViewController, C> {
37x
82
        DestinationStep(CurrentViewControllerStep(windowProvider: windowProvider))
37x
83
    }
37x
84
85
    /// Returns the resulting view controller of the finder provided.
86
    public static func custom<F: Finder>(using finder: F) -> DestinationStep<F.ViewController, F.Context> {
7x
87
        DestinationStep(FinderStep(finder: finder))
7x
88
    }
7x
89
90
}