AXorcist/Sources/axorc/Core/InputHandler.swift
Peter Steinberger cebf27a814 style: apply formatting and code cleanup
Standardize code style across all AXorcist source and test files
2025-11-12 15:32:27 +00:00

119 lines
5.0 KiB
Swift

// InputHandler.swift - Handles input parsing for AXORC CLI
import AXorcist // For ax...Log helpers
import Foundation
enum InputHandler {
// MARK: Internal
struct ParseResult {
let jsonString: String?
let sourceDescription: String
let error: String?
}
typealias Result = ParseResult
static func parseInput(
stdin: Bool,
file: String?,
json: String?,
directPayload: String?) -> ParseResult
{
axDebugLog("InputHandler: Parsing input...")
let activeInputFlags = (stdin ? 1 : 0) + (file != nil ? 1 : 0) + (json != nil ? 1 : 0)
let positionalPayloadProvided = directPayload != nil &&
!(directPayload?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true)
if activeInputFlags > 1 {
return self.handleMultipleInputFlags()
} else if stdin {
return self.handleStdinInput()
} else if let filePath = file {
return self.handleFileInput(filePath: filePath)
} else if let jsonString = json {
axDebugLog("Using --json flag with payload of \(jsonString.count) characters.")
let trimmedJsonString = jsonString.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmedJsonString.isEmpty {
let error = "Error: --json argument was provided but the string is empty or only whitespace."
axErrorLog(error)
return ParseResult(jsonString: nil, sourceDescription: "--json argument", error: error)
}
return ParseResult(jsonString: trimmedJsonString, sourceDescription: "--json argument", error: nil)
} else if positionalPayloadProvided {
return self.handleDirectPayload(directPayload: directPayload)
} else {
return self.handleNoInput()
}
}
// MARK: Private
// MARK: - Helper Functions
private static func handleMultipleInputFlags() -> ParseResult {
let error = "Error: Multiple input flags specified (--stdin, --file, --json). Only one is allowed."
axErrorLog(error)
return ParseResult(jsonString: nil, sourceDescription: error, error: error)
}
private static func handleStdinInput() -> ParseResult {
let stdInputHandle = FileHandle.standardInput
let stdinData = stdInputHandle.readDataToEndOfFile()
if let str = String(data: stdinData, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines),
!str.isEmpty
{
axDebugLog("Successfully read \(str.count) characters from STDIN.")
return ParseResult(jsonString: str, sourceDescription: "STDIN", error: nil)
} else {
let error = "No data received from STDIN or data was empty."
axErrorLog("Failed to read from STDIN or received empty data.")
return ParseResult(jsonString: nil, sourceDescription: "STDIN", error: error)
}
}
private static func handleFileInput(
filePath: String) -> ParseResult
{
let sourceDescription = "File: \(filePath)"
do {
let rawFileContent = try String(contentsOfFile: filePath, encoding: .utf8) // Read raw
axDebugLog(
"HFI_DEBUG: Raw file content for [\(filePath)]: '\(rawFileContent)' (length: \(rawFileContent.count))")
let str = rawFileContent.trimmingCharacters(in: .whitespacesAndNewlines)
axDebugLog("HFI_DEBUG: Trimmed file content: '\(str)' (length: \(str.count))")
if !str.isEmpty {
axDebugLog("Successfully read \(str.count) characters from file: \(filePath)")
return ParseResult(jsonString: str, sourceDescription: sourceDescription, error: nil)
} else {
let error = "File \(filePath) is empty or contains only whitespace."
axWarningLog("File \(filePath) was empty or contained only whitespace.")
return ParseResult(jsonString: nil, sourceDescription: sourceDescription, error: error)
}
} catch {
let errorMsg = "Failed to read file \(filePath): \(error.localizedDescription)"
axErrorLog("Error reading file \(filePath): \(error)")
return ParseResult(jsonString: nil, sourceDescription: sourceDescription, error: errorMsg)
}
}
private static func handleDirectPayload(
directPayload: String?) -> ParseResult
{
let jsonString = directPayload?.trimmingCharacters(in: .whitespacesAndNewlines)
axDebugLog("Using direct payload argument with \(jsonString?.count ?? 0) characters.")
return ParseResult(jsonString: jsonString, sourceDescription: "Direct argument", error: nil)
}
private static func handleNoInput() -> ParseResult {
let error = "No JSON input method specified"
axErrorLog("No input method specified and no direct payload provided.")
return ParseResult(jsonString: nil, sourceDescription: "No input", error: error)
}
}