CHGenerator/Sources/Generator/Templates/Template.swift

62 lines
2.1 KiB
Swift
Raw Normal View History

2022-08-16 10:39:05 +02:00
import Foundation
protocol Template {
associatedtype Key where Key: RawRepresentable, Key.RawValue == String, Key: CaseIterable, Key: Hashable
static var templateName: String { get }
var raw: String { get }
2022-12-02 10:25:54 +01:00
var results: GenerationResultsHandler { get }
init(raw: String, results: GenerationResultsHandler)
2022-08-16 10:39:05 +02:00
}
extension Template {
2022-12-02 10:25:54 +01:00
init(in folder: URL, results: GenerationResultsHandler) throws {
2022-08-16 10:39:05 +02:00
let url = folder.appendingPathComponent(Self.templateName)
2022-12-02 10:25:54 +01:00
try self.init(from: url, results: results)
2022-08-16 10:39:05 +02:00
}
2022-12-02 10:25:54 +01:00
init(from url: URL, results: GenerationResultsHandler) throws {
let raw = try String(contentsOf: url)
2022-12-02 10:25:54 +01:00
self.init(raw: raw, results: results)
2022-08-16 10:39:05 +02:00
}
func generate(_ content: [Key : String], to url: URL) -> Bool {
2022-08-16 10:39:05 +02:00
let content = generate(content)
2022-12-02 10:25:54 +01:00
#warning("log.write(content, to: url, file: )")
return true
2022-08-16 10:39:05 +02:00
}
func generate(_ content: [Key : String], shouldIndent: Bool = false) -> String {
var result = raw.components(separatedBy: "\n")
Key.allCases.forEach { key in
let newContent = content[key]?.withoutEmptyLines ?? ""
let stringMarker = "<!--\(key.rawValue)-->"
let indices = result.enumerated().filter { $0.element.contains(stringMarker) }
.map { $0.offset }
guard !indices.isEmpty else {
return
}
for index in indices {
let old = result[index].components(separatedBy: stringMarker)
// Add indentation to all added lines
let indentation = old.first!
guard shouldIndent, indentation.trimmingCharacters(in: .whitespaces).isEmpty else {
// Prefix is not indentation, so just insert new content
result[index] = old.joined(separator: newContent)
continue
}
let indentedReplacements = newContent.indented(by: indentation)
result[index] = old.joined(separator: indentedReplacements)
}
}
return result.joined(separator: "\n").withoutEmptyLines
}
}