Created
January 18, 2017 23:33
-
-
Save BenziAhamed/97e51a35bcdb8e42e74a14601a97680e to your computer and use it in GitHub Desktop.
My lame little templating engine in Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
// more of a POC | |
// not production ready | |
protocol PropertyReflectable { } | |
extension PropertyReflectable { | |
subscript(property key: String) -> Any? { | |
let mirror = Mirror(reflecting: self) | |
for child in mirror.children where child.label == key { | |
return child.value | |
} | |
return nil | |
} | |
var properties: [String] { | |
return Mirror(reflecting: self).children.flatMap { $0.label } | |
} | |
} | |
struct Templater { | |
static func format(text: String, model: PropertyReflectable) -> String { | |
var output = text | |
for property in model.properties { | |
if let value = model[property: property] { | |
output = output.replacingOccurrences(of: "{{\(property)}}", with: "\(value)") | |
} | |
} | |
return output | |
} | |
static func format(text: String, model: [String: PropertyReflectable]) -> String { | |
var output = text | |
for (_, kv) in model.enumerated() { | |
for property in kv.value.properties { | |
let key = "\(kv.key).\(property)" | |
if let value = kv.value[property: property] { | |
output = output.replacingOccurrences(of: "{{\(key)}}", with: "\(value)") | |
} | |
} | |
} | |
return output | |
} | |
} | |
struct Person { | |
let name: String | |
let age: Int | |
} | |
extension Person : PropertyReflectable { } | |
let me = Person(name: "Benzi", age: 5) | |
Templater.format( | |
text: "my name is {{name}}, i am {{age}} years old", | |
model: me | |
) | |
// my name is Benzi, i am 5 years old" | |
struct Product { | |
let name: String | |
let price: Decimal | |
} | |
extension Product : PropertyReflectable { } | |
let book = Product(name: "Starting Swift", price: 9.99) | |
Templater.format( | |
text: "{{user.name}} just bought {{product.name}} ({{product.price}})", | |
model: [ | |
"user": me, | |
"product": book | |
] | |
) | |
// "Benzi just bought Starting Swift (9.99)" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment