mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
118 lines
3.9 KiB
Swift
118 lines
3.9 KiB
Swift
/// \brief A thing into which we can stream text
|
|
protocol FormattedOutputStream {
|
|
func append(text: String)
|
|
}
|
|
|
|
/// \brief Every String can be used as a FormattedOutputStream
|
|
/// directly
|
|
extension String: FormattedOutputStream {
|
|
func append(text: String)
|
|
}
|
|
|
|
/// \brief A thing that can be printed in the REPL and the Debugger
|
|
///
|
|
/// Everything compiler-magically conforms to this protocol. To
|
|
/// change the debug representation for a type, you don't need to
|
|
/// declare conformance: simply give the type a debugFormat().
|
|
protocol DebugPrintable {
|
|
typealias DebugFormatter: Formattable = String
|
|
|
|
/// \brief Produce a textual representation for the REPL and
|
|
/// Debugger.
|
|
///
|
|
/// Because String is a Formattable, your implementation of
|
|
/// debugFormat can just return a String. If you want to write
|
|
/// directly to the FormattedOutputStream for efficiency reasons,
|
|
/// (e.g. if your representation is huge), you can return a custom
|
|
/// DebugFormatter type.
|
|
///
|
|
/// NOTE: producing a representation that can be consumed by the
|
|
/// REPL to produce an equivalent object is strongly encouraged
|
|
/// where possible! For example, String.debugFormat() produces a
|
|
/// representation containing quotes, where special characters are
|
|
/// escaped, etc. A struct Point { var x, y: Int } might be
|
|
/// represented as "Point(x: 3, y: 5)".
|
|
func debugFormat() -> DebugFormatter
|
|
}
|
|
|
|
/// \brief A thing that can be print()ed toString()ed.
|
|
///
|
|
/// Conformance to Printable is explicit, but if you want to use the
|
|
/// debugFormat() results for your type's printFormat(), all you need
|
|
/// to do is declare conformance to Printable, and there's nothing to
|
|
/// implement.
|
|
///
|
|
/// Note: explicitness here keeps us from automatically polluting
|
|
/// completion results for every type with printFormat() and
|
|
/// toString() functions.
|
|
protocol Printable: DebugPrintable {
|
|
typealias PrintFormatter: Formattable = DebugFormatter
|
|
|
|
/// \brief produce a "pretty" textual representation that can be
|
|
/// distinct from the debug format. For example,
|
|
/// String.printFormat returns the string itself, without quoting.
|
|
///
|
|
/// In general you can return a String here, but if you need more
|
|
/// control, we strongly recommend returning a custom Formatter
|
|
/// type, e.g. a nested struct of your type. If you're lazy, you
|
|
/// can conform to Formattable directly and just implement its
|
|
/// write() func.
|
|
func printFormat() -> PrintFormatter {
|
|
return debugFormat()
|
|
}
|
|
|
|
/// \brief Simply convert to String
|
|
///
|
|
/// Don't reimplement this: the default implementation always works.
|
|
/// If you must reimplement toString(), make sure its results are
|
|
/// consistent with those of printFormat() (i.e. you shouldn't
|
|
/// change the behavior).
|
|
func toString() -> String {
|
|
var result: String
|
|
this.printFormat().write(result)
|
|
return result
|
|
}
|
|
}
|
|
|
|
/// \brief A thing that can write into a FormattedOutputStream. Every
|
|
/// Formattable is also a Printable, naturally.
|
|
protocol Formattable: Printable {
|
|
func write(
|
|
target: [byref] FormattedOutputStream,
|
|
width: Int? = None, precision: Int? = None, right_align: Bool? = None)
|
|
|
|
// You'll never want to reimplement this
|
|
func printFormat() -> PrintFormatter {
|
|
return this
|
|
}
|
|
|
|
/// \brief get the debug representation.
|
|
///
|
|
/// A Formattable will usually want to override this, so that in the
|
|
/// debugger and REPL, it doesn't appear to be the thing on whose
|
|
/// behalf it is formatting.
|
|
func debugFormat() -> DebugFormatter {
|
|
return this
|
|
}
|
|
}
|
|
|
|
extension String: Formattable {
|
|
func write(
|
|
target: [byref] FormattedOutputStream, knobs
|
|
width: Int? = None, precision: Int? = None, right_align: Bool? = None
|
|
) {
|
|
...
|
|
}
|
|
|
|
func debugFormat() -> String {
|
|
...escape all the CodePoints...
|
|
}
|
|
|
|
// Swift may get us this default automatically from the protocol,
|
|
// but it's here as a reminder of how String behaves.
|
|
func printFormat() -> String {
|
|
return this
|
|
}
|
|
}
|
|
|