Emcee
70 строк · 3.0 Кб
1import Foundation
2import PathLib
3import ProcessController
4import ResourceLocation
5
6private class ResolvableResourceLocationArg: SubprocessArgument, CustomStringConvertible {
7private let resolvableResourceLocation: ResolvableResourceLocation
8private let implicitFilenameInArchive: String?
9
10enum ArgError: Error, CustomStringConvertible {
11case cannotResolve(ResolvableResourceLocation, containerPath: AbsolutePath)
12
13var description: String {
14switch self {
15case .cannotResolve(let resolvableResourceLocation, let containerPath):
16return "Unable to generate direct local path for resource location '\(resolvableResourceLocation)': "
17+ "the location is not accessible directly, and it has been fetched into container path '\(containerPath)'. "
18+ "But it is not possible to determine a file inside container as no file name was provided in the resource location. "
19+ "You can provide a filename inside archive via URL fragment, e.g. http://example.com/archive.zip#filename"
20}
21}
22}
23
24public init(
25resolvableResourceLocation: ResolvableResourceLocation,
26implicitFilenameInArchive: String?
27) {
28self.resolvableResourceLocation = resolvableResourceLocation
29self.implicitFilenameInArchive = implicitFilenameInArchive
30}
31
32public func stringValue() throws -> String {
33let result = try resolvableResourceLocation.resolve()
34switch result {
35case .directlyAccessibleFile(let path):
36return try path.stringValue()
37case .contentsOfArchive(let containerPath, let filenameInArchive):
38if let filenameInArchive = filenameInArchive {
39return try containerPath.appending(filenameInArchive).stringValue()
40} else if let implicitFilenameInArchive = implicitFilenameInArchive {
41return try containerPath.appending(implicitFilenameInArchive).stringValue()
42} else {
43throw ArgError.cannotResolve(resolvableResourceLocation, containerPath: containerPath)
44}
45}
46}
47
48public var description: String {
49switch resolvableResourceLocation.resourceLocation {
50case .localFilePath(let path):
51return path
52case .remoteUrl(let url, _):
53var items = ["url: \(url)"]
54if let implicitFilenameInArchive = implicitFilenameInArchive {
55items.append("file: \(implicitFilenameInArchive)")
56}
57return "<\(type(of: self)): " + items.joined(separator: " ") + ">"
58}
59}
60}
61
62public extension ResolvableResourceLocation {
63func asArgumentWith(implicitFilenameInArchive: String) -> SubprocessArgument {
64return ResolvableResourceLocationArg(resolvableResourceLocation: self, implicitFilenameInArchive: implicitFilenameInArchive)
65}
66
67func asArgument() -> SubprocessArgument {
68return ResolvableResourceLocationArg(resolvableResourceLocation: self, implicitFilenameInArchive: nil)
69}
70}
71