/// A type that provides data extraction and manipulation functions from relative path representations. enum PathProvider { // MARK: Functions /// Extracts the root *DocC* archive relative path from a given URL relative path. /// /// Given that the provided URL relative path is expected to have the prefix `/archives/archive-name`, then a root *DocC* archive generated out of the /// archive name obtained from the URL relative path is returned. Otherwise, an empty string is returned. /// /// - Parameter path: A URL relative path from where to extract data. /// - Returns: A URL relative path to a root *DocC* archive or an empty string . static func archivePath(from path: String) -> String { let pathComponents = path.split(separator: .forwardSlash) return pathComponents.count > 1 ? .init(format: .Format.Path.archive, String(pathComponents[1])) : .empty } /// Extracts the name of the *DocC* archive from a given URL relative path. /// /// Given that the provided URL relative path is expected to have the prefix `/archives/archive-name`, then a lowercased archive name from the URL /// relative path is returned. Otherwise, an empty string is returned. /// /// - Parameter path: A URL relative path from where to extract data. /// - Returns: A lowercased name of the archive or an empty string. static func archiveName(from path: String) -> String { let pathComponents = path.split(separator: .forwardSlash) return pathComponents.count > 1 ? .init(pathComponents[1]).lowercased() : .empty } /// Extracts the name of the *DocC* archive from a given URL relative path. /// /// Given that the provided URL relative path is expected to have the format `/archives/archive-name/path/to/resource`, then the path to a /// resource extracted from the URL relative path is returned. Otherwise, a forward slash string is returned. /// /// - Parameter path: A URL relative path from where to extract data. /// - Returns: A URL relative path to a resource or a forward slash. static func resourcePath(from path: String) -> String { let matches = path.matches(of: /\//) return matches.count > 2 ? .init(path[matches[2].startIndex...]) : .forwardSlash } } // MARK: - Character+Constants private extension Character { static let forwardSlash: Character = "/" }