Add HBMustacheCustomRenderable
Support custom rendering of swift types Fixes tests that rely on NSNull
This commit is contained in:
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
.build
|
||||
.git
|
||||
29
Sources/HummingbirdMustache/CustomRenderable.swift
Normal file
29
Sources/HummingbirdMustache/CustomRenderable.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Hummingbird server framework project
|
||||
//
|
||||
// Copyright (c) 2021-2021 the Hummingbird authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
import Foundation
|
||||
|
||||
protocol HBMustacheCustomRenderable {
|
||||
var renderText: String { get }
|
||||
var isNull: Bool { get }
|
||||
}
|
||||
|
||||
extension HBMustacheCustomRenderable {
|
||||
var renderText: String { String(describing: self) }
|
||||
var isNull: Bool { false }
|
||||
}
|
||||
|
||||
extension NSNull: HBMustacheCustomRenderable {
|
||||
public var renderText: String { "" }
|
||||
public var isNull: Bool { true }
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
import Foundation
|
||||
|
||||
extension HBMustacheTemplate {
|
||||
/// Render template using object
|
||||
@@ -46,14 +47,20 @@ extension HBMustacheTemplate {
|
||||
if let child = getChild(named: variable, transform: transform, context: context) {
|
||||
if let template = child as? HBMustacheTemplate {
|
||||
return template.render(context: context)
|
||||
} else if let renderable = child as? HBMustacheCustomRenderable {
|
||||
return context.contentType.escapeText(renderable.renderText)
|
||||
} else {
|
||||
return context.contentType.escapeText(String(describing: child))
|
||||
}
|
||||
}
|
||||
case .unescapedVariable(let variable, let transform):
|
||||
if let child = getChild(named: variable, transform: transform, context: context) {
|
||||
if let renderable = child as? HBMustacheCustomRenderable {
|
||||
return renderable.renderText
|
||||
} else {
|
||||
return String(describing: child)
|
||||
}
|
||||
}
|
||||
case .section(let variable, let transform, let template):
|
||||
let child = self.getChild(named: variable, transform: transform, context: context)
|
||||
return self.renderSection(child, with: template, context: context)
|
||||
@@ -94,6 +101,8 @@ extension HBMustacheTemplate {
|
||||
return bool ? template.render(context: context) : ""
|
||||
case let lambda as HBMustacheLambda:
|
||||
return lambda.run(context.stack.last!, template)
|
||||
case let null as HBMustacheCustomRenderable where null.isNull == true:
|
||||
return ""
|
||||
case .some(let value):
|
||||
return template.render(context: context.withObject(value))
|
||||
case .none:
|
||||
@@ -113,6 +122,8 @@ extension HBMustacheTemplate {
|
||||
return array.renderInvertedSection(with: template, context: context)
|
||||
case let bool as Bool:
|
||||
return bool ? "" : template.render(context: context)
|
||||
case let null as HBMustacheCustomRenderable where null.isNull == true:
|
||||
return template.render(context: context)
|
||||
case .some:
|
||||
return ""
|
||||
case .none:
|
||||
|
||||
@@ -22,8 +22,8 @@ import XCTest
|
||||
public struct AnyDecodable: Decodable {
|
||||
public let value: Any
|
||||
|
||||
public init<T>(_ value: T?) {
|
||||
self.value = value ?? ()
|
||||
public init<T>(_ value: T) {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,11 +32,7 @@ public extension AnyDecodable {
|
||||
let container = try decoder.singleValueContainer()
|
||||
|
||||
if container.decodeNil() {
|
||||
#if canImport(Foundation)
|
||||
self.init(NSNull())
|
||||
#else
|
||||
self.init(Self?.none)
|
||||
#endif
|
||||
} else if let bool = try? container.decode(Bool.self) {
|
||||
self.init(bool)
|
||||
} else if let int = try? container.decode(Int.self) {
|
||||
|
||||
Reference in New Issue
Block a user