Files
swiftpm-mustache/Sources/Mustache/Transform.swift
T. R. Bernstein 6061715025
Some checks failed
CI / macOS (push) Has been cancelled
CI / linux (swift:6.0) (push) Has been cancelled
CI / linux (swift:6.1) (push) Has been cancelled
CI / linux (swift:6.2) (push) Has been cancelled
CI / windows (6.1) (push) Has been cancelled
Adapt project for Astzweig
2025-09-29 15:03:48 +02:00

232 lines
6.5 KiB
Swift

/// Objects that can have a transforms run on them. Mustache transforms are specific to this implementation
/// of Mustache. They allow you to process objects before they are rendered.
///
/// The syntax for applying transforms is `{{transform(variable)}}`. Transforms can be applied to both
/// variables, sections and inverted sections.
///
/// A simple example would be ensuring a string is lowercase.
/// ```
/// {{lowercased(myString)}}
/// ```
/// If applying a transform to a sequence then the closing element of the sequence should include the
/// transform name eg
/// ```
/// {{#reversed(sequence)}}{{.}}{{\reversed(sequence)}}
/// ```
public protocol MustacheTransformable {
func transform(_ name: String) -> Any?
}
extension StringProtocol {
/// Transform String/Substring
///
/// Transforms available are `capitalized`, `lowercased`, `uppercased` and `reversed`
/// - Parameter name: transform name
/// - Returns: Result
public func transform(_ name: String) -> Any? {
switch name {
case "empty":
return isEmpty
case "capitalized":
return capitalized
case "lowercased":
return lowercased()
case "uppercased":
return uppercased()
case "reversed":
return Substring(self.reversed())
default:
return nil
}
}
}
extension String: MustacheTransformable {}
extension Substring: MustacheTransformable {}
/// Protocol for sequence that can be sorted
private protocol ComparableSequence {
func comparableTransform(_ name: String) -> Any?
}
extension Array: MustacheTransformable {
/// Transform Array.
///
/// Transforms available are `first`, `last`, `reversed`, `count`, `empty` and for arrays
/// with comparable elements `sorted`.
/// - Parameter name: transform name
/// - Returns: Result
public func transform(_ name: String) -> Any? {
switch name {
case "first":
return first
case "last":
return last
case "reversed":
return reversed()
case "count":
return count
case "empty":
return isEmpty
default:
if let comparableSeq = self as? ComparableSequence {
return comparableSeq.comparableTransform(name)
}
return nil
}
}
}
extension Array: ComparableSequence where Element: Comparable {
func comparableTransform(_ name: String) -> Any? {
switch name {
case "sorted":
return sorted()
default:
return nil
}
}
}
extension Set: MustacheTransformable {
/// Transform Set.
///
/// Transforms available are `count`, `empty` and for sets
/// with comparable elements `sorted`.
/// - Parameter name: transform name
/// - Returns: Result
public func transform(_ name: String) -> Any? {
switch name {
case "count":
return count
case "empty":
return isEmpty
default:
if let comparableSeq = self as? ComparableSequence {
return comparableSeq.comparableTransform(name)
}
return nil
}
}
}
extension Set: ComparableSequence where Element: Comparable {
func comparableTransform(_ name: String) -> Any? {
switch name {
case "sorted":
return sorted()
default:
return nil
}
}
}
extension ReversedCollection: MustacheTransformable {
/// Transform ReversedCollection.
///
/// Transforms available are `first`, `last`, `reversed`, `count`, `empty` and for collections
/// with comparable elements `sorted`.
/// - Parameter name: transform name
/// - Returns: Result
public func transform(_ name: String) -> Any? {
switch name {
case "first":
return first
case "last":
return last
case "reversed":
return reversed()
case "count":
return count
case "empty":
return isEmpty
default:
if let comparableSeq = self as? ComparableSequence {
return comparableSeq.comparableTransform(name)
}
return nil
}
}
}
extension ReversedCollection: ComparableSequence where Element: Comparable {
func comparableTransform(_ name: String) -> Any? {
switch name {
case "sorted":
return sorted()
default:
return nil
}
}
}
extension Dictionary: MustacheTransformable {
/// Transform Dictionary
///
/// Transforms available are `count`, `enumerated` and for dictionaries
/// with comparable keys `sorted`.
/// - Parameter name: transform name
/// - Returns: Result
public func transform(_ name: String) -> Any? {
switch name {
case "count":
return count
case "empty":
return isEmpty
case "enumerated":
return map { (key: $0.key, value: $0.value) }
default:
if let comparableSeq = self as? ComparableSequence {
return comparableSeq.comparableTransform(name)
}
return nil
}
}
}
extension Dictionary: ComparableSequence where Key: Comparable {
func comparableTransform(_ name: String) -> Any? {
switch name {
case "sorted":
return map { (key: $0.key, value: $0.value) }.sorted { $0.key < $1.key }
default:
return nil
}
}
}
extension FixedWidthInteger {
/// Transform FixedWidthInteger
///
/// Transforms available are `plusone`, `minusone`, `odd`, `even`
/// - Parameter name: transform name
/// - Returns: Result
public func transform(_ name: String) -> Any? {
switch name {
case "equalzero":
return self == 0
case "plusone":
return self + 1
case "minusone":
return self - 1
case "even":
return (self & 1) == 0
case "odd":
return (self & 1) == 1
default:
return nil
}
}
}
extension Int: MustacheTransformable {}
extension Int8: MustacheTransformable {}
extension Int16: MustacheTransformable {}
extension Int32: MustacheTransformable {}
extension Int64: MustacheTransformable {}
extension UInt: MustacheTransformable {}
extension UInt8: MustacheTransformable {}
extension UInt16: MustacheTransformable {}
extension UInt32: MustacheTransformable {}
extension UInt64: MustacheTransformable {}