CustomDebugStringConvertible - new line character formatting

Hi

Overview

  • I have a custom type Car for which I have implemented CustomDebugStringConvertible
  • I have used new line character in debugDescription
  • For individual elements it seems ok

Problem

  • While printing an array of cars ([Car]) the formatting is not correct

Expected output

  • Works with individual elements
  • Works with array elements with new elements beginning in a new line, like Car B and Car C beginning in a new line

Questions

  • How can I fix this for array while still working with individual elements?
  • Is there a better solution?
  • How is it done for other types that use new line characters?

Example:

struct Car: CustomDebugStringConvertible {
    let id: Int
    let name: String
    let parts: [String]
    
    var debugDescription: String {
        """
        Car: id: \(id) name: \(name)
        \(parts.map { "  - " + $0 }.joined(separator: "\n"))
        """
    }
}

let c1 = Car(id: 1, name: "Car A", parts: ["Gearbox", "Wheels", "Doors"])
let c2 = Car(id: 2, name: "Car B", parts: ["Gearbox", "Doors"])
let c3 = Car(id: 3, name: "Car C", parts: ["Wheels", "Doors"])

let cars = [c1, c2, c3]

print(c1)
print("=======")
print(cars)
Output
Car: id: 1 name: Car A
  - Gearbox
  - Wheels
  - Doors
=======
[Car: id: 1 name: Car A
  - Gearbox
  - Wheels
  - Doors, Car: id: 2 name: Car B
  - Gearbox
  - Doors, Car: id: 3 name: Car C
  - Wheels
  - Doors]

I think the last item in the joined parts is missing the newline character at the end.

As a remedy, you could just append a newline character.

struct Car: CustomDebugStringConvertible {
    let id: Int
    let name: String
    let parts: [String]
    
    var debugDescription: String {
        let v = parts.map { "  - " + $0 }
        let tail = v.joined (separator: "\n")
        let u = """
        Car: id: \(id) name: \(name)
        \(tail)
        """
        return u + "\n"
    }
}

But then you would have to deal with the extra newline character if it matters when printing individual cars.

1 Like

Thanks @ibex

Not sure if I am nitpicking, yeah the new line character while printing individual Car is not ideal.

Just curious how it is done for other cases, like for example Date uses newline characters but works well in an array or when a single date is printed

How is the formatting done for types like Date which use new line character when printed?

Or is there a better approach to solve this?

Yes, we encountered this problem in the standard library too. And our best solution was...not using line breaks:

2 Likes

Thanks a lot @xwu, I thought I was the only one facing this.

I was ignorantly hoping there would be a way to replace the separator to \n while printing (print / os log) the sequence.