Add HBMustacheCustomRenderable

Support custom rendering of swift types
Fixes tests that rely on NSNull
This commit is contained in:
Adam Fowler
2021-05-03 15:33:28 +01:00
parent f852bc1d00
commit 4a78d44712
4 changed files with 45 additions and 7 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
.build
.git

View 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 }
}

View File

@@ -11,6 +11,7 @@
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import Foundation
extension HBMustacheTemplate {
/// Render template using object
@@ -46,13 +47,19 @@ 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) {
return String(describing: child)
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)
@@ -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:

View File

@@ -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) {