mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
150 lines
5.1 KiB
Swift
150 lines
5.1 KiB
Swift
import Foundation
|
|
|
|
struct URLTemplateProcessor {
|
|
static func processTemplate(_ template: String, with parameters: [String: String]) -> String {
|
|
var processedURL = template
|
|
let extractedParams = extractParameters(from: template)
|
|
|
|
for param in extractedParams {
|
|
let placeholder = "{\(param.name)" + (param.defaultValue != nil ? ",default=\(param.defaultValue!)" : "") + "}"
|
|
let value = parameters[param.name] ?? param.defaultValue ?? ""
|
|
processedURL = processedURL.replacingOccurrences(of: placeholder, with: value)
|
|
}
|
|
|
|
return processedURL
|
|
}
|
|
|
|
static func extractParameters(from template: String) -> [TemplateParameter] {
|
|
var parameters: [TemplateParameter] = []
|
|
let pattern = "\\{([^,}]+)(?:,default=([^}]+))?\\}"
|
|
|
|
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
|
|
return parameters
|
|
}
|
|
|
|
let matches = regex.matches(in: template, options: [], range: NSRange(location: 0, length: template.utf16.count))
|
|
|
|
for match in matches {
|
|
let nameRange = match.range(at: 1)
|
|
let defaultRange = match.range(at: 2)
|
|
|
|
if let nameSwiftRange = Range(nameRange, in: template) {
|
|
let name = String(template[nameSwiftRange])
|
|
var defaultValue: String? = nil
|
|
|
|
if defaultRange.location != NSNotFound,
|
|
let defaultSwiftRange = Range(defaultRange, in: template) {
|
|
defaultValue = String(template[defaultSwiftRange])
|
|
}
|
|
|
|
parameters.append(TemplateParameter(name: name, defaultValue: defaultValue))
|
|
}
|
|
}
|
|
|
|
return parameters
|
|
}
|
|
|
|
static func validateTemplate(_ template: String) -> Bool {
|
|
let extractedParams = extractParameters(from: template)
|
|
|
|
// Check if all placeholders are valid
|
|
let pattern = "\\{[^{}]*\\}"
|
|
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
|
|
return false
|
|
}
|
|
|
|
let matches = regex.matches(in: template, options: [], range: NSRange(location: 0, length: template.utf16.count))
|
|
|
|
// Each match should correspond to a valid parameter
|
|
for match in matches {
|
|
if let matchRange = Range(match.range, in: template) {
|
|
let matchString = String(template[matchRange])
|
|
let isValid = extractedParams.contains { param in
|
|
matchString.contains(param.name)
|
|
}
|
|
if !isValid {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
static func getRequiredParameters(from template: String) -> [String] {
|
|
return extractParameters(from: template)
|
|
.filter { $0.defaultValue == nil }
|
|
.map { $0.name }
|
|
}
|
|
|
|
static func hasParameters(_ template: String) -> Bool {
|
|
return template.contains("{") && template.contains("}")
|
|
}
|
|
}
|
|
|
|
struct TemplateParameter {
|
|
let name: String
|
|
let defaultValue: String?
|
|
|
|
var isRequired: Bool {
|
|
return defaultValue == nil
|
|
}
|
|
}
|
|
|
|
// MARK: - Template Examples and Helpers
|
|
extension URLTemplateProcessor {
|
|
static let commonTemplates: [TemplateExample] = [
|
|
TemplateExample(
|
|
name: "Google Search",
|
|
template: "https://google.com/search?q={query}",
|
|
description: "Search Google with a custom query"
|
|
),
|
|
TemplateExample(
|
|
name: "GitHub Repository",
|
|
template: "https://github.com/{user}/{repo}",
|
|
description: "Open a GitHub repository"
|
|
),
|
|
TemplateExample(
|
|
name: "YouTube Video",
|
|
template: "https://youtube.com/watch?v={videoId}",
|
|
description: "Open a YouTube video"
|
|
),
|
|
TemplateExample(
|
|
name: "Maps Location",
|
|
template: "https://maps.apple.com/?q={location,default=New York}",
|
|
description: "Open a location in Apple Maps"
|
|
),
|
|
TemplateExample(
|
|
name: "Wikipedia Article",
|
|
template: "https://en.wikipedia.org/wiki/{article}",
|
|
description: "Open a Wikipedia article"
|
|
)
|
|
]
|
|
|
|
static func suggestTemplate(for url: String) -> String? {
|
|
// Simple template suggestion based on common patterns
|
|
if url.contains("google.com/search") {
|
|
return url.replacingOccurrences(of: "q=[^&]*", with: "q={query}", options: .regularExpression)
|
|
} else if url.contains("github.com") && url.components(separatedBy: "/").count >= 5 {
|
|
let components = url.components(separatedBy: "/")
|
|
if components.count >= 5 {
|
|
return "https://github.com/{user}/{repo}"
|
|
}
|
|
} else if url.contains("youtube.com/watch") {
|
|
return url.replacingOccurrences(of: "v=[^&]*", with: "v={videoId}", options: .regularExpression)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
struct TemplateExample {
|
|
let name: String
|
|
let template: String
|
|
let description: String
|
|
|
|
var parameters: [TemplateParameter] {
|
|
return URLTemplateProcessor.extractParameters(from: template)
|
|
}
|
|
}
|