I am trying to pretty-print (with indentation for child objects) a composite object structure where the parent and each of the child objects confirm to the CustomDebugStringConvertible protocol.
My code so far is: import Foundation
class StringUtils {
static func appendIfValuePresent(key: String, value: AnyHashable?, toArray array: inout [String], separator: String = ": ") {
if let value = value {
array.append("\(key)\(separator)\(value)")
}
}
}
class Address: CustomDebugStringConvertible {
var city: String? = "B'lore"
var country: String? = "India"
var pincode: String? = nil
var debugDescription: String {
var components = [String]()
StringUtils.appendIfValuePresent(key: "city", value: city, toArray: &components)
StringUtils.appendIfValuePresent(key: "country", value: country, toArray: &components)
StringUtils.appendIfValuePresent(key: "pincode", value: pincode, toArray: &components)
let debugStr = components.joined(separator: "\n")
return debugStr
}
}
class Contact: CustomDebugStringConvertible {
var phNum: String? = "111-222-33"
var email: String? = "[email protected]"
var address: Address? = Address()
var debugDescription: String {
var components = [String]()
StringUtils.appendIfValuePresent(key: "phNum", value: phNum, toArray: &components)
StringUtils.appendIfValuePresent(key: "email", value: email, toArray: &components)
StringUtils.appendIfValuePresent(key: "address", value: address?.debugDescription, toArray: &components, separator: ":\n")
let debugStr = components.joined(separator: "\n")
return debugStr
}
}
class Student: CustomDebugStringConvertible {
var name = "ron"
var contact: Contact? = Contact()
var debugDescription: String {
var components = [String]()
StringUtils.appendIfValuePresent(key: "name", value: name, toArray: &components)
StringUtils.appendIfValuePresent(key: "contact", value: contact?.debugDescription, toArray: &components, separator: ":\n")
let debugStr = components.joined(separator: "\n")
return debugStr
}
}
let student = Student()
print(student)
The output of the above code snippet is:
// Actual output
/*
name: ron
contact:
phNum: 111-222-33
email: [email protected]
address:
city: B'lore
country: India
*/
However, I would like to print like this:
// Expected output
/*
name: ron
contact:
phNum: 111-222-33
email: [email protected]
address:
city: B'lore
country: India
*/
What is the best way to achieve this, retaining the generic structure of the code?
I could devise a solution to my problem and posted a solution here: https://gist.github.com/raunakp/16155d19d005939f1297b7c6cb6f890c
import Foundation