Files
swiftpm-stencil/Sources/Environment.swift

73 lines
2.3 KiB
Swift

public struct Environment {
public let templateClass: Template.Type
public var extensions: [Extension]
public var loader: Loader?
public var errorReporter: ErrorReporter
public init(loader: Loader? = nil,
extensions: [Extension]? = nil,
templateClass: Template.Type = Template.self,
errorReporter: ErrorReporter = SimpleErrorReporter()) {
self.templateClass = templateClass
self.errorReporter = errorReporter
self.loader = loader
self.extensions = (extensions ?? []) + [DefaultExtension()]
}
public func loadTemplate(name: String) throws -> Template {
if let loader = loader {
return try loader.loadTemplate(name: name, environment: self)
} else {
throw TemplateDoesNotExist(templateNames: [name], loader: nil)
}
}
public func loadTemplate(names: [String]) throws -> Template {
if let loader = loader {
return try loader.loadTemplate(names: names, environment: self)
} else {
throw TemplateDoesNotExist(templateNames: names, loader: nil)
}
}
public func renderTemplate(name: String, context: [String: Any]? = nil) throws -> String {
let template = try loadTemplate(name: name)
return try render(template: template, context: context)
}
public func renderTemplate(string: String, context: [String: Any]? = nil) throws -> String {
let template = templateClass.init(templateString: string, environment: self)
return try render(template: template, context: context)
}
func render(template: Template, context: [String: Any]?) throws -> String {
errorReporter.context = ErrorReporterContext(template: template)
do {
return try template.render(context)
} catch {
throw errorReporter.reportError(error)
}
}
var template: Template? {
return errorReporter.context?.template
}
public func pushTemplate<Result>(_ template: Template, token: Token?, closure: (() throws -> Result)) rethrows -> Result {
let errorReporterContext = errorReporter.context
defer { errorReporter.context = errorReporterContext }
errorReporter.context = ErrorReporterContext(
template: template,
parent: errorReporterContext != nil ? (errorReporterContext!, token) : nil
)
do {
return try closure()
} catch {
throw errorReporter.reportError(error)
}
}
}