Initial project setup - Phases 1-3 complete

This commit is contained in:
Trey t
2026-04-06 11:28:40 -05:00
commit c77e506db5
293 changed files with 14233 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
import Foundation
public struct ParsedCURLRequest: Sendable {
public var method: String = "GET"
public var url: String = ""
public var headers: [(key: String, value: String)] = []
public var body: String?
}
public enum CURLParser {
public static func parse(_ curlString: String) -> ParsedCURLRequest? {
var result = ParsedCURLRequest()
let trimmed = curlString.trimmingCharacters(in: .whitespacesAndNewlines)
guard trimmed.lowercased().hasPrefix("curl") else { return nil }
let tokens = tokenize(trimmed)
var i = 0
while i < tokens.count {
let token = tokens[i]
switch token {
case "curl":
break
case "-X", "--request":
i += 1
if i < tokens.count {
result.method = tokens[i].uppercased()
}
case "-H", "--header":
i += 1
if i < tokens.count {
let header = tokens[i]
if let colonIndex = header.firstIndex(of: ":") {
let key = String(header[header.startIndex..<colonIndex]).trimmingCharacters(in: .whitespaces)
let value = String(header[header.index(after: colonIndex)...]).trimmingCharacters(in: .whitespaces)
result.headers.append((key: key, value: value))
}
}
case "-d", "--data", "--data-raw", "--data-binary":
i += 1
if i < tokens.count {
result.body = tokens[i]
if result.method == "GET" {
result.method = "POST"
}
}
default:
if !token.hasPrefix("-") && result.url.isEmpty {
result.url = token
}
}
i += 1
}
return result.url.isEmpty ? nil : result
}
private static func tokenize(_ input: String) -> [String] {
var tokens: [String] = []
var current = ""
var inSingleQuote = false
var inDoubleQuote = false
var escaped = false
for char in input {
if escaped {
current.append(char)
escaped = false
continue
}
if char == "\\" && !inSingleQuote {
escaped = true
continue
}
if char == "'" && !inDoubleQuote {
inSingleQuote.toggle()
continue
}
if char == "\"" && !inSingleQuote {
inDoubleQuote.toggle()
continue
}
if char.isWhitespace && !inSingleQuote && !inDoubleQuote {
if !current.isEmpty {
tokens.append(current)
current = ""
}
continue
}
current.append(char)
}
if !current.isEmpty {
tokens.append(current)
}
return tokens
}
}