Swift format, swift 5.3
This commit is contained in:
23
.swiftformat
Normal file
23
.swiftformat
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Minimum swiftformat version
|
||||||
|
--minversion 0.47.4
|
||||||
|
|
||||||
|
# Swift version
|
||||||
|
--swiftversion 5.3
|
||||||
|
|
||||||
|
# file options
|
||||||
|
--exclude .build
|
||||||
|
|
||||||
|
# rules
|
||||||
|
--disable redundantReturn, extensionAccessControl
|
||||||
|
|
||||||
|
# format options
|
||||||
|
--ifdef no-indent
|
||||||
|
--nospaceoperators ...,..<
|
||||||
|
--patternlet inline
|
||||||
|
--self insert
|
||||||
|
--stripunusedargs unnamed-only
|
||||||
|
|
||||||
|
#--maxwidth 150
|
||||||
|
--wraparguments before-first
|
||||||
|
--wrapparameters before-first
|
||||||
|
--wrapcollections before-first
|
||||||
@@ -28,10 +28,10 @@ public struct HBMustacheLambda {
|
|||||||
/// Initialize `HBMustacheLambda`
|
/// Initialize `HBMustacheLambda`
|
||||||
/// - Parameter cb: function to be called by lambda
|
/// - Parameter cb: function to be called by lambda
|
||||||
public init(_ cb: @escaping Callback) {
|
public init(_ cb: @escaping Callback) {
|
||||||
callback = cb
|
self.callback = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func run(_ object: Any, _ template: HBMustacheTemplate) -> String {
|
internal func run(_ object: Any, _ template: HBMustacheTemplate) -> String {
|
||||||
return callback(object, template)
|
return self.callback(object, template)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
public final class HBMustacheLibrary {
|
public final class HBMustacheLibrary {
|
||||||
/// Initialize empty library
|
/// Initialize empty library
|
||||||
public init() {
|
public init() {
|
||||||
templates = [:]
|
self.templates = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize library with contents of folder.
|
/// Initialize library with contents of folder.
|
||||||
@@ -17,7 +17,7 @@ public final class HBMustacheLibrary {
|
|||||||
/// - Parameter directory: Directory to look for mustache templates
|
/// - Parameter directory: Directory to look for mustache templates
|
||||||
/// - Parameter extension: Extension of files to look for
|
/// - Parameter extension: Extension of files to look for
|
||||||
public init(directory: String, withExtension extension: String = "mustache") throws {
|
public init(directory: String, withExtension extension: String = "mustache") throws {
|
||||||
templates = [:]
|
self.templates = [:]
|
||||||
try loadTemplates(from: directory, withExtension: `extension`)
|
try loadTemplates(from: directory, withExtension: `extension`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,14 +27,14 @@ public final class HBMustacheLibrary {
|
|||||||
/// - name: Name of template
|
/// - name: Name of template
|
||||||
public func register(_ template: HBMustacheTemplate, named name: String) {
|
public func register(_ template: HBMustacheTemplate, named name: String) {
|
||||||
template.setLibrary(self)
|
template.setLibrary(self)
|
||||||
templates[name] = template
|
self.templates[name] = template
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return template registed with name
|
/// Return template registed with name
|
||||||
/// - Parameter name: name to search for
|
/// - Parameter name: name to search for
|
||||||
/// - Returns: Template
|
/// - Returns: Template
|
||||||
public func getTemplate(named name: String) -> HBMustacheTemplate? {
|
public func getTemplate(named name: String) -> HBMustacheTemplate? {
|
||||||
templates[name]
|
self.templates[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render object using templated with name
|
/// Render object using templated with name
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ public struct HBParser {
|
|||||||
/// Create a Reader object
|
/// Create a Reader object
|
||||||
/// - Parameter string: String to parse
|
/// - Parameter string: String to parse
|
||||||
init(_ string: String) {
|
init(_ string: String) {
|
||||||
_storage = Storage(string)
|
self._storage = Storage(string)
|
||||||
position = string.startIndex
|
self.position = string.startIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer: String { return _storage.buffer }
|
var buffer: String { return self._storage.buffer }
|
||||||
private(set) var position: String.Index
|
private(set) var position: String.Index
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: Current character
|
/// - Returns: Current character
|
||||||
mutating func character() throws -> Character {
|
mutating func character() throws -> Character {
|
||||||
guard !reachedEnd() else { throw HBParser.Error.overflow }
|
guard !self.reachedEnd() else { throw HBParser.Error.overflow }
|
||||||
let c = unsafeCurrent()
|
let c = unsafeCurrent()
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
return c
|
return c
|
||||||
@@ -54,11 +54,11 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: If current character was the one we expected
|
/// - Returns: If current character was the one we expected
|
||||||
mutating func read(string: String) throws -> Bool {
|
mutating func read(string: String) throws -> Bool {
|
||||||
let initialPosition = position
|
let initialPosition = self.position
|
||||||
guard string.count > 0 else { return true }
|
guard string.count > 0 else { return true }
|
||||||
let subString = try read(count: string.count)
|
let subString = try read(count: string.count)
|
||||||
guard subString == string else {
|
guard subString == string else {
|
||||||
position = initialPosition
|
self.position = initialPosition
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -79,9 +79,9 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: The string read from the buffer
|
/// - Returns: The string read from the buffer
|
||||||
mutating func read(count: Int) throws -> Substring {
|
mutating func read(count: Int) throws -> Substring {
|
||||||
guard buffer.distance(from: position, to: buffer.endIndex) >= count else { throw HBParser.Error.overflow }
|
guard self.buffer.distance(from: self.position, to: self.buffer.endIndex) >= count else { throw HBParser.Error.overflow }
|
||||||
let end = buffer.index(position, offsetBy: count)
|
let end = self.buffer.index(self.position, offsetBy: count)
|
||||||
let subString = buffer[position ..< end]
|
let subString = self.buffer[self.position..<end]
|
||||||
unsafeAdvance(by: count)
|
unsafeAdvance(by: count)
|
||||||
return subString
|
return subString
|
||||||
}
|
}
|
||||||
@@ -91,10 +91,10 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow if we hit the end of the buffer before reading character
|
/// - Throws: .overflow if we hit the end of the buffer before reading character
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(until: Character, throwOnOverflow: Bool = true) throws -> Substring {
|
@discardableResult mutating func read(until: Character, throwOnOverflow: Bool = true) throws -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
while !reachedEnd() {
|
while !self.reachedEnd() {
|
||||||
if unsafeCurrent() == until {
|
if unsafeCurrent() == until {
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ extension HBParser {
|
|||||||
unsafeSetPosition(startIndex)
|
unsafeSetPosition(startIndex)
|
||||||
throw HBParser.Error.overflow
|
throw HBParser.Error.overflow
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read from buffer until we hit a string. By default the position after this is of the beginning of the string we were checking for
|
/// Read from buffer until we hit a string. By default the position after this is of the beginning of the string we were checking for
|
||||||
@@ -113,21 +113,21 @@ extension HBParser {
|
|||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(untilString: String, throwOnOverflow: Bool = true, skipToEnd: Bool = false) throws -> Substring {
|
@discardableResult mutating func read(untilString: String, throwOnOverflow: Bool = true, skipToEnd: Bool = false) throws -> Substring {
|
||||||
guard untilString.count > 0 else { return "" }
|
guard untilString.count > 0 else { return "" }
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
var foundIndex = position
|
var foundIndex = self.position
|
||||||
var untilIndex = untilString.startIndex
|
var untilIndex = untilString.startIndex
|
||||||
while !reachedEnd() {
|
while !self.reachedEnd() {
|
||||||
if unsafeCurrent() == untilString[untilIndex] {
|
if unsafeCurrent() == untilString[untilIndex] {
|
||||||
if untilIndex == untilString.startIndex {
|
if untilIndex == untilString.startIndex {
|
||||||
foundIndex = position
|
foundIndex = self.position
|
||||||
}
|
}
|
||||||
untilIndex = untilString.index(after: untilIndex)
|
untilIndex = untilString.index(after: untilIndex)
|
||||||
if untilIndex == untilString.endIndex {
|
if untilIndex == untilString.endIndex {
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
if skipToEnd == false {
|
if skipToEnd == false {
|
||||||
position = foundIndex
|
self.position = foundIndex
|
||||||
}
|
}
|
||||||
let result = buffer[startIndex ..< foundIndex]
|
let result = self.buffer[startIndex..<foundIndex]
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -136,10 +136,10 @@ extension HBParser {
|
|||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
if throwOnOverflow {
|
if throwOnOverflow {
|
||||||
position = startIndex
|
self.position = startIndex
|
||||||
throw Error.overflow
|
throw Error.overflow
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read from buffer until we hit a character in supplied set. Position after this is of the character we were checking for
|
/// Read from buffer until we hit a character in supplied set. Position after this is of the character we were checking for
|
||||||
@@ -147,10 +147,10 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(until characterSet: Set<Character>, throwOnOverflow: Bool = true) throws -> Substring {
|
@discardableResult mutating func read(until characterSet: Set<Character>, throwOnOverflow: Bool = true) throws -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
while !reachedEnd() {
|
while !self.reachedEnd() {
|
||||||
if characterSet.contains(unsafeCurrent()) {
|
if characterSet.contains(unsafeCurrent()) {
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ extension HBParser {
|
|||||||
unsafeSetPosition(startIndex)
|
unsafeSetPosition(startIndex)
|
||||||
throw HBParser.Error.overflow
|
throw HBParser.Error.overflow
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read from buffer until keyPath on character returns true. Position after this is of the character we were checking for
|
/// Read from buffer until keyPath on character returns true. Position after this is of the character we were checking for
|
||||||
@@ -166,18 +166,18 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(until keyPath: KeyPath<Character, Bool>, throwOnOverflow: Bool = true) throws -> Substring {
|
@discardableResult mutating func read(until keyPath: KeyPath<Character, Bool>, throwOnOverflow: Bool = true) throws -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
while !reachedEnd() {
|
while !self.reachedEnd() {
|
||||||
if current()[keyPath: keyPath] {
|
if current()[keyPath: keyPath] {
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
if throwOnOverflow {
|
if throwOnOverflow {
|
||||||
position = startIndex
|
self.position = startIndex
|
||||||
throw Error.overflow
|
throw Error.overflow
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read from buffer until keyPath on character returns true. Position after this is of the character we were checking for
|
/// Read from buffer until keyPath on character returns true. Position after this is of the character we were checking for
|
||||||
@@ -185,26 +185,26 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(until cb: (Character) -> Bool, throwOnOverflow: Bool = true) throws -> Substring {
|
@discardableResult mutating func read(until cb: (Character) -> Bool, throwOnOverflow: Bool = true) throws -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
while !reachedEnd() {
|
while !self.reachedEnd() {
|
||||||
if cb(current()) {
|
if cb(current()) {
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
if throwOnOverflow {
|
if throwOnOverflow {
|
||||||
position = startIndex
|
self.position = startIndex
|
||||||
throw Error.overflow
|
throw Error.overflow
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read from buffer from current position until the end of the buffer
|
/// Read from buffer from current position until the end of the buffer
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func readUntilTheEnd() -> Substring {
|
@discardableResult mutating func readUntilTheEnd() -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
position = buffer.endIndex
|
self.position = self.buffer.endIndex
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read while character at current position is the one supplied
|
/// Read while character at current position is the one supplied
|
||||||
@@ -212,7 +212,7 @@ extension HBParser {
|
|||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(while: Character) -> Int {
|
@discardableResult mutating func read(while: Character) -> Int {
|
||||||
var count = 0
|
var count = 0
|
||||||
while !reachedEnd(),
|
while !self.reachedEnd(),
|
||||||
unsafeCurrent() == `while`
|
unsafeCurrent() == `while`
|
||||||
{
|
{
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
@@ -225,38 +225,38 @@ extension HBParser {
|
|||||||
/// - Parameter while: keyPath to check
|
/// - Parameter while: keyPath to check
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(while keyPath: KeyPath<Character, Bool>) -> Substring {
|
@discardableResult mutating func read(while keyPath: KeyPath<Character, Bool>) -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
while !reachedEnd(),
|
while !self.reachedEnd(),
|
||||||
unsafeCurrent()[keyPath: keyPath]
|
unsafeCurrent()[keyPath: keyPath]
|
||||||
{
|
{
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read while character at current position is in supplied set
|
/// Read while character at current position is in supplied set
|
||||||
/// - Parameter while: character set to check
|
/// - Parameter while: character set to check
|
||||||
/// - Returns: String read from buffer
|
/// - Returns: String read from buffer
|
||||||
@discardableResult mutating func read(while characterSet: Set<Character>) -> Substring {
|
@discardableResult mutating func read(while characterSet: Set<Character>) -> Substring {
|
||||||
let startIndex = position
|
let startIndex = self.position
|
||||||
while !reachedEnd(),
|
while !self.reachedEnd(),
|
||||||
characterSet.contains(unsafeCurrent())
|
characterSet.contains(unsafeCurrent())
|
||||||
{
|
{
|
||||||
unsafeAdvance()
|
unsafeAdvance()
|
||||||
}
|
}
|
||||||
return buffer[startIndex ..< position]
|
return self.buffer[startIndex..<self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return whether we have reached the end of the buffer
|
/// Return whether we have reached the end of the buffer
|
||||||
/// - Returns: Have we reached the end
|
/// - Returns: Have we reached the end
|
||||||
func reachedEnd() -> Bool {
|
func reachedEnd() -> Bool {
|
||||||
return position == buffer.endIndex
|
return self.position == self.buffer.endIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return whether we are at the start of the buffer
|
/// Return whether we are at the start of the buffer
|
||||||
/// - Returns: Are we are the start
|
/// - Returns: Are we are the start
|
||||||
func atStart() -> Bool {
|
func atStart() -> Bool {
|
||||||
return position == buffer.startIndex
|
return self.position == self.buffer.startIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +286,7 @@ extension HBParser {
|
|||||||
let line = try! parser.read(until: Character("\n"), throwOnOverflow: false)
|
let line = try! parser.read(until: Character("\n"), throwOnOverflow: false)
|
||||||
// count new lines up to this current position
|
// count new lines up to this current position
|
||||||
let buffer = parser.buffer
|
let buffer = parser.buffer
|
||||||
let textBefore = buffer[buffer.startIndex ..< position]
|
let textBefore = buffer[buffer.startIndex..<self.position]
|
||||||
let lineNumber = textBefore.filter { $0.isNewline }.count
|
let lineNumber = textBefore.filter { $0.isNewline }.count
|
||||||
|
|
||||||
return Context(line: String(line), lineNumber: lineNumber + 1, columnNumber: columnNumber + 1)
|
return Context(line: String(line), lineNumber: lineNumber + 1, columnNumber: columnNumber + 1)
|
||||||
@@ -299,21 +299,21 @@ extension HBParser {
|
|||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
/// - Returns: Character
|
/// - Returns: Character
|
||||||
func current() -> Character {
|
func current() -> Character {
|
||||||
guard !reachedEnd() else { return "\0" }
|
guard !self.reachedEnd() else { return "\0" }
|
||||||
return unsafeCurrent()
|
return unsafeCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move forward one character
|
/// Move forward one character
|
||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
mutating func advance() throws {
|
mutating func advance() throws {
|
||||||
guard !reachedEnd() else { throw HBParser.Error.overflow }
|
guard !self.reachedEnd() else { throw HBParser.Error.overflow }
|
||||||
return unsafeAdvance()
|
return unsafeAdvance()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move back one character
|
/// Move back one character
|
||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
mutating func retreat() throws {
|
mutating func retreat() throws {
|
||||||
guard position != buffer.startIndex else { throw HBParser.Error.overflow }
|
guard self.position != self.buffer.startIndex else { throw HBParser.Error.overflow }
|
||||||
return unsafeRetreat()
|
return unsafeRetreat()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ extension HBParser {
|
|||||||
/// - Parameter amount: number of characters to move forward
|
/// - Parameter amount: number of characters to move forward
|
||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
mutating func advance(by amount: Int) throws {
|
mutating func advance(by amount: Int) throws {
|
||||||
guard buffer.distance(from: position, to: buffer.endIndex) >= amount else { throw HBParser.Error.overflow }
|
guard self.buffer.distance(from: self.position, to: self.buffer.endIndex) >= amount else { throw HBParser.Error.overflow }
|
||||||
return unsafeAdvance(by: amount)
|
return unsafeAdvance(by: amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,12 +329,12 @@ extension HBParser {
|
|||||||
/// - Parameter amount: number of characters to move back
|
/// - Parameter amount: number of characters to move back
|
||||||
/// - Throws: .overflow
|
/// - Throws: .overflow
|
||||||
mutating func retreat(by amount: Int) throws {
|
mutating func retreat(by amount: Int) throws {
|
||||||
guard buffer.distance(from: buffer.startIndex, to: position) >= amount else { throw HBParser.Error.overflow }
|
guard self.buffer.distance(from: self.buffer.startIndex, to: self.position) >= amount else { throw HBParser.Error.overflow }
|
||||||
return unsafeRetreat(by: amount)
|
return unsafeRetreat(by: amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func setPosition(_ position: String.Index) throws {
|
mutating func setPosition(_ position: String.Index) throws {
|
||||||
guard position <= buffer.endIndex else { throw HBParser.Error.overflow }
|
guard position <= self.buffer.endIndex else { throw HBParser.Error.overflow }
|
||||||
unsafeSetPosition(position)
|
unsafeSetPosition(position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,23 +342,23 @@ extension HBParser {
|
|||||||
// unsafe versions without checks
|
// unsafe versions without checks
|
||||||
extension HBParser {
|
extension HBParser {
|
||||||
func unsafeCurrent() -> Character {
|
func unsafeCurrent() -> Character {
|
||||||
return buffer[position]
|
return self.buffer[self.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func unsafeAdvance() {
|
mutating func unsafeAdvance() {
|
||||||
position = buffer.index(after: position)
|
self.position = self.buffer.index(after: self.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func unsafeRetreat() {
|
mutating func unsafeRetreat() {
|
||||||
position = buffer.index(before: position)
|
self.position = self.buffer.index(before: self.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func unsafeAdvance(by amount: Int) {
|
mutating func unsafeAdvance(by amount: Int) {
|
||||||
position = buffer.index(position, offsetBy: amount)
|
self.position = self.buffer.index(self.position, offsetBy: amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func unsafeRetreat(by amount: Int) {
|
mutating func unsafeRetreat(by amount: Int) {
|
||||||
position = buffer.index(position, offsetBy: -amount)
|
self.position = self.buffer.index(self.position, offsetBy: -amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func unsafeSetPosition(_ position: String.Index) {
|
mutating func unsafeSetPosition(_ position: String.Index) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ struct HBMustacheSequenceContext: HBMustacheTransformable {
|
|||||||
init(first: Bool = false, last: Bool = false) {
|
init(first: Bool = false, last: Bool = false) {
|
||||||
self.first = first
|
self.first = first
|
||||||
self.last = last
|
self.last = last
|
||||||
index = 0
|
self.index = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform `HBMustacheContext`. These are available when processing elements
|
/// Transform `HBMustacheContext`. These are available when processing elements
|
||||||
@@ -25,15 +25,15 @@ struct HBMustacheSequenceContext: HBMustacheTransformable {
|
|||||||
func transform(_ name: String) -> Any? {
|
func transform(_ name: String) -> Any? {
|
||||||
switch name {
|
switch name {
|
||||||
case "first":
|
case "first":
|
||||||
return first
|
return self.first
|
||||||
case "last":
|
case "last":
|
||||||
return last
|
return self.last
|
||||||
case "index":
|
case "index":
|
||||||
return index
|
return self.index
|
||||||
case "even":
|
case "even":
|
||||||
return (index & 1) == 0
|
return (self.index & 1) == 0
|
||||||
case "odd":
|
case "odd":
|
||||||
return (index & 1) == 1
|
return (self.index & 1) == 1
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ extension HBMustacheTemplate {
|
|||||||
var endDelimiter: String
|
var endDelimiter: String
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
sectionName = nil
|
self.sectionName = nil
|
||||||
newLine = true
|
self.newLine = true
|
||||||
startDelimiter = "{{"
|
self.startDelimiter = "{{"
|
||||||
endDelimiter = "}}"
|
self.endDelimiter = "}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
func withSectionName(_ name: String, method: String? = nil) -> ParserState {
|
func withSectionName(_ name: String, method: String? = nil) -> ParserState {
|
||||||
@@ -58,7 +58,7 @@ extension HBMustacheTemplate {
|
|||||||
static func parse(_ string: String) throws -> [Token] {
|
static func parse(_ string: String) throws -> [Token] {
|
||||||
var parser = HBParser(string)
|
var parser = HBParser(string)
|
||||||
do {
|
do {
|
||||||
return try parse(&parser, state: .init())
|
return try self.parse(&parser, state: .init())
|
||||||
} catch {
|
} catch {
|
||||||
throw ParserError(context: parser.getContext(), error: error)
|
throw ParserError(context: parser.getContext(), error: error)
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ extension HBMustacheTemplate {
|
|||||||
// section
|
// section
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let (name, method) = try parseName(&parser, state: state)
|
let (name, method) = try parseName(&parser, state: state)
|
||||||
if isStandalone(&parser, state: state) {
|
if self.isStandalone(&parser, state: state) {
|
||||||
setNewLine = true
|
setNewLine = true
|
||||||
} else if whiteSpaceBefore.count > 0 {
|
} else if whiteSpaceBefore.count > 0 {
|
||||||
tokens.append(.text(String(whiteSpaceBefore)))
|
tokens.append(.text(String(whiteSpaceBefore)))
|
||||||
@@ -112,7 +112,7 @@ extension HBMustacheTemplate {
|
|||||||
// inverted section
|
// inverted section
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let (name, method) = try parseName(&parser, state: state)
|
let (name, method) = try parseName(&parser, state: state)
|
||||||
if isStandalone(&parser, state: state) {
|
if self.isStandalone(&parser, state: state) {
|
||||||
setNewLine = true
|
setNewLine = true
|
||||||
} else if whiteSpaceBefore.count > 0 {
|
} else if whiteSpaceBefore.count > 0 {
|
||||||
tokens.append(.text(String(whiteSpaceBefore)))
|
tokens.append(.text(String(whiteSpaceBefore)))
|
||||||
@@ -130,7 +130,7 @@ extension HBMustacheTemplate {
|
|||||||
parser.unsafeSetPosition(position)
|
parser.unsafeSetPosition(position)
|
||||||
throw Error.sectionCloseNameIncorrect
|
throw Error.sectionCloseNameIncorrect
|
||||||
}
|
}
|
||||||
if isStandalone(&parser, state: state) {
|
if self.isStandalone(&parser, state: state) {
|
||||||
setNewLine = true
|
setNewLine = true
|
||||||
} else if whiteSpaceBefore.count > 0 {
|
} else if whiteSpaceBefore.count > 0 {
|
||||||
tokens.append(.text(String(whiteSpaceBefore)))
|
tokens.append(.text(String(whiteSpaceBefore)))
|
||||||
@@ -141,8 +141,8 @@ extension HBMustacheTemplate {
|
|||||||
case "!":
|
case "!":
|
||||||
// comment
|
// comment
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
_ = try parseComment(&parser, state: state)
|
_ = try self.parseComment(&parser, state: state)
|
||||||
setNewLine = isStandalone(&parser, state: state)
|
setNewLine = self.isStandalone(&parser, state: state)
|
||||||
|
|
||||||
case "{":
|
case "{":
|
||||||
// unescaped variable
|
// unescaped variable
|
||||||
@@ -172,7 +172,7 @@ extension HBMustacheTemplate {
|
|||||||
if whiteSpaceBefore.count > 0 {
|
if whiteSpaceBefore.count > 0 {
|
||||||
tokens.append(.text(String(whiteSpaceBefore)))
|
tokens.append(.text(String(whiteSpaceBefore)))
|
||||||
}
|
}
|
||||||
if isStandalone(&parser, state: state) {
|
if self.isStandalone(&parser, state: state) {
|
||||||
setNewLine = true
|
setNewLine = true
|
||||||
tokens.append(.partial(name, indentation: String(whiteSpaceBefore)))
|
tokens.append(.partial(name, indentation: String(whiteSpaceBefore)))
|
||||||
} else {
|
} else {
|
||||||
@@ -183,8 +183,8 @@ extension HBMustacheTemplate {
|
|||||||
case "=":
|
case "=":
|
||||||
// set delimiter
|
// set delimiter
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
state = try parserSetDelimiter(&parser, state: state)
|
state = try self.parserSetDelimiter(&parser, state: state)
|
||||||
setNewLine = isStandalone(&parser, state: state)
|
setNewLine = self.isStandalone(&parser, state: state)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// variable
|
// variable
|
||||||
@@ -232,20 +232,20 @@ extension HBMustacheTemplate {
|
|||||||
/// parse variable name
|
/// parse variable name
|
||||||
static func parseName(_ parser: inout HBParser, state: ParserState) throws -> (String, String?) {
|
static func parseName(_ parser: inout HBParser, state: ParserState) throws -> (String, String?) {
|
||||||
parser.read(while: \.isWhitespace)
|
parser.read(while: \.isWhitespace)
|
||||||
let text = String(parser.read(while: sectionNameChars))
|
let text = String(parser.read(while: self.sectionNameChars))
|
||||||
parser.read(while: \.isWhitespace)
|
parser.read(while: \.isWhitespace)
|
||||||
guard try parser.read(string: state.endDelimiter) else { throw Error.unfinishedName }
|
guard try parser.read(string: state.endDelimiter) else { throw Error.unfinishedName }
|
||||||
|
|
||||||
// does the name include brackets. If so this is a method call
|
// does the name include brackets. If so this is a method call
|
||||||
var nameParser = HBParser(String(text))
|
var nameParser = HBParser(String(text))
|
||||||
let string = nameParser.read(while: sectionNameCharsWithoutBrackets)
|
let string = nameParser.read(while: self.sectionNameCharsWithoutBrackets)
|
||||||
if nameParser.reachedEnd() {
|
if nameParser.reachedEnd() {
|
||||||
return (text, nil)
|
return (text, nil)
|
||||||
} else {
|
} else {
|
||||||
// parse function parameter, as we have just parsed a function name
|
// parse function parameter, as we have just parsed a function name
|
||||||
guard nameParser.current() == "(" else { throw Error.unfinishedName }
|
guard nameParser.current() == "(" else { throw Error.unfinishedName }
|
||||||
nameParser.unsafeAdvance()
|
nameParser.unsafeAdvance()
|
||||||
let string2 = nameParser.read(while: sectionNameCharsWithoutBrackets)
|
let string2 = nameParser.read(while: self.sectionNameCharsWithoutBrackets)
|
||||||
guard nameParser.current() == ")" else { throw Error.unfinishedName }
|
guard nameParser.current() == ")" else { throw Error.unfinishedName }
|
||||||
nameParser.unsafeAdvance()
|
nameParser.unsafeAdvance()
|
||||||
guard nameParser.reachedEnd() else { throw Error.unfinishedName }
|
guard nameParser.reachedEnd() else { throw Error.unfinishedName }
|
||||||
@@ -290,7 +290,7 @@ extension HBMustacheTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func isStandalone(_ parser: inout HBParser, state: ParserState) -> Bool {
|
static func isStandalone(_ parser: inout HBParser, state: ParserState) -> Bool {
|
||||||
return state.newLine && hasLineFinished(&parser)
|
return state.newLine && self.hasLineFinished(&parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static let sectionNameCharsWithoutBrackets = Set<Character>("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._?")
|
private static let sectionNameCharsWithoutBrackets = Set<Character>("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._?")
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ extension HBMustacheTemplate {
|
|||||||
if string.last == "\n" {
|
if string.last == "\n" {
|
||||||
string += indentation
|
string += indentation
|
||||||
}
|
}
|
||||||
string += renderToken(token, stack: stack, context: context)
|
string += self.renderToken(token, stack: stack, context: context)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for token in tokens {
|
for token in tokens {
|
||||||
string += renderToken(token, stack: stack, context: context)
|
string += self.renderToken(token, stack: stack, context: context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string
|
return string
|
||||||
@@ -25,9 +25,9 @@ extension HBMustacheTemplate {
|
|||||||
|
|
||||||
func renderToken(_ token: Token, stack: [Any], context: HBMustacheSequenceContext? = nil) -> String {
|
func renderToken(_ token: Token, stack: [Any], context: HBMustacheSequenceContext? = nil) -> String {
|
||||||
switch token {
|
switch token {
|
||||||
case let .text(text):
|
case .text(let text):
|
||||||
return text
|
return text
|
||||||
case let .variable(variable, method):
|
case .variable(let variable, let method):
|
||||||
if let child = getChild(named: variable, from: stack, method: method, context: context) {
|
if let child = getChild(named: variable, from: stack, method: method, context: context) {
|
||||||
if let template = child as? HBMustacheTemplate {
|
if let template = child as? HBMustacheTemplate {
|
||||||
return template.render(stack)
|
return template.render(stack)
|
||||||
@@ -35,19 +35,19 @@ extension HBMustacheTemplate {
|
|||||||
return String(describing: child).htmlEscape()
|
return String(describing: child).htmlEscape()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .unescapedVariable(variable, method):
|
case .unescapedVariable(let variable, let method):
|
||||||
if let child = getChild(named: variable, from: stack, method: method, context: context) {
|
if let child = getChild(named: variable, from: stack, method: method, context: context) {
|
||||||
return String(describing: child)
|
return String(describing: child)
|
||||||
}
|
}
|
||||||
case let .section(variable, method, template):
|
case .section(let variable, let method, let template):
|
||||||
let child = getChild(named: variable, from: stack, method: method, context: context)
|
let child = self.getChild(named: variable, from: stack, method: method, context: context)
|
||||||
return renderSection(child, stack: stack, with: template)
|
return self.renderSection(child, stack: stack, with: template)
|
||||||
|
|
||||||
case let .invertedSection(variable, method, template):
|
case .invertedSection(let variable, let method, let template):
|
||||||
let child = getChild(named: variable, from: stack, method: method, context: context)
|
let child = self.getChild(named: variable, from: stack, method: method, context: context)
|
||||||
return renderInvertedSection(child, stack: stack, with: template)
|
return self.renderInvertedSection(child, stack: stack, with: template)
|
||||||
|
|
||||||
case let .partial(name, indentation):
|
case .partial(let name, let indentation):
|
||||||
if let template = library?.getTemplate(named: name) {
|
if let template = library?.getTemplate(named: name) {
|
||||||
return template.render(stack, indentation: indentation)
|
return template.render(stack, indentation: indentation)
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ extension HBMustacheTemplate {
|
|||||||
return bool ? template.render(stack) : ""
|
return bool ? template.render(stack) : ""
|
||||||
case let lambda as HBMustacheLambda:
|
case let lambda as HBMustacheLambda:
|
||||||
return lambda.run(stack.last!, template)
|
return lambda.run(stack.last!, template)
|
||||||
case let .some(value):
|
case .some(let value):
|
||||||
return template.render(stack + [value])
|
return template.render(stack + [value])
|
||||||
case .none:
|
case .none:
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ public final class HBMustacheTemplate {
|
|||||||
/// - Parameter string: Template text
|
/// - Parameter string: Template text
|
||||||
/// - Throws: HBMustacheTemplate.Error
|
/// - Throws: HBMustacheTemplate.Error
|
||||||
public init(string: String) throws {
|
public init(string: String) throws {
|
||||||
tokens = try Self.parse(string)
|
self.tokens = try Self.parse(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render object using this template
|
/// Render object using this template
|
||||||
/// - Parameter object: Object to render
|
/// - Parameter object: Object to render
|
||||||
/// - Returns: Rendered text
|
/// - Returns: Rendered text
|
||||||
public func render(_ object: Any) -> String {
|
public func render(_ object: Any) -> String {
|
||||||
render([object], context: nil)
|
self.render([object], context: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(_ tokens: [Token]) {
|
internal init(_ tokens: [Token]) {
|
||||||
@@ -20,9 +20,9 @@ public final class HBMustacheTemplate {
|
|||||||
|
|
||||||
internal func setLibrary(_ library: HBMustacheLibrary) {
|
internal func setLibrary(_ library: HBMustacheLibrary) {
|
||||||
self.library = library
|
self.library = library
|
||||||
for token in tokens {
|
for token in self.tokens {
|
||||||
switch token {
|
switch token {
|
||||||
case let .section(_, _, template), let .invertedSection(_, _, template):
|
case .section(_, _, let template), .invertedSection(_, _, let template):
|
||||||
template.setLibrary(library)
|
template.setLibrary(library)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -42,15 +42,15 @@ extension HBMustacheTemplate: Equatable {
|
|||||||
extension HBMustacheTemplate.Token: Equatable {
|
extension HBMustacheTemplate.Token: Equatable {
|
||||||
public static func == (lhs: HBMustacheTemplate.Token, rhs: HBMustacheTemplate.Token) -> Bool {
|
public static func == (lhs: HBMustacheTemplate.Token, rhs: HBMustacheTemplate.Token) -> Bool {
|
||||||
switch (lhs, rhs) {
|
switch (lhs, rhs) {
|
||||||
case let (.text(lhs), .text(rhs)):
|
case (.text(let lhs), .text(let rhs)):
|
||||||
return lhs == rhs
|
return lhs == rhs
|
||||||
case let (.variable(lhs, lhs2), .variable(rhs, rhs2)):
|
case (.variable(let lhs, let lhs2), .variable(let rhs, let rhs2)):
|
||||||
return lhs == rhs && lhs2 == rhs2
|
return lhs == rhs && lhs2 == rhs2
|
||||||
case let (.section(lhs1, lhs2, lhs3), .section(rhs1, rhs2, rhs3)):
|
case (.section(let lhs1, let lhs2, let lhs3), .section(let rhs1, let rhs2, let rhs3)):
|
||||||
return lhs1 == rhs1 && lhs2 == rhs2 && lhs3 == rhs3
|
return lhs1 == rhs1 && lhs2 == rhs2 && lhs3 == rhs3
|
||||||
case let (.invertedSection(lhs1, lhs2, lhs3), .invertedSection(rhs1, rhs2, rhs3)):
|
case (.invertedSection(let lhs1, let lhs2, let lhs3), .invertedSection(let rhs1, let rhs2, let rhs3)):
|
||||||
return lhs1 == rhs1 && lhs2 == rhs2 && lhs3 == rhs3
|
return lhs1 == rhs1 && lhs2 == rhs2 && lhs3 == rhs3
|
||||||
case let (.partial(name1, indent1), .partial(name2, indent2)):
|
case (.partial(let name1, let indent1), .partial(let name2, let indent2)):
|
||||||
return name1 == name2 && indent1 == indent2
|
return name1 == name2 && indent1 == indent2
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
""")
|
""")
|
||||||
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
|
||||||
let date = Date()
|
let date = Date()
|
||||||
for _ in 1 ... 10000 {
|
for _ in 1...10000 {
|
||||||
_ = template.render(object)
|
_ = template.render(object)
|
||||||
}
|
}
|
||||||
print(-date.timeIntervalSinceNow)
|
print(-date.timeIntervalSinceNow)
|
||||||
|
|||||||
Reference in New Issue
Block a user