Refactor core::format
Explanation
The core::format
namespace has served a very useful purpose since it was written, but it is
cumbersome for a number of reasons:
- Having to use
std::string
because String
isn't finished yet / unicode handling is hard /
cyclic dependency (because String
also needs a format()
method)
- Possibility of running out of memory due to accumulating a structure when we might not necessarily
need to, e.g. if we're formatting directly to stdout
- It's not true formatting: it mainly just builds a nice representation of the internal structure of
an object and its subobjects, but it can't really mix and match that representation with anything
- It's only customizable on a very shallow level (indent size); stuff like colorization, multiline /
not multiline, maximum length before abbreviation, etc. is all not configurable
Task
Re-write core::format
to satisfy the following requirements:
- It must only allocate memory if the result is going to be stored in memory; if it is writing to a
file or a socket or some other data sink, the formatting result should go directly to that
destination
- It should support interpolating the format results into static strings (while upholding the
no-allocation requirement above)
- It should not use
std::string
; instead, the output should be written as UTF-8 into a
String<Utf8>
(or at least a DynamicArray<char8_t>
)
- It should support customization at the point of the format call (probably through some kind of
format specifier syntax like you see in
std::printf()
)
The most likely best implementation for this type of system will be passing a mutable reference to
some kind of "sink" structure down through the format()
methods of each subobject, allowing each
to write its information to the sink. That means that format()
will no longer return anything,
instead leaving the sink to compose the parts or just write them as is.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Refactor `core::format`
## Explanation
The `core::format` namespace has served a very useful purpose since it was written, but it is
cumbersome for a number of reasons:
- Having to use `std::string` because `String` isn't finished yet / unicode handling is hard /
cyclic dependency (because `String` also needs a `format()` method)
- Possibility of running out of memory due to accumulating a structure when we might not necessarily
need to, e.g. if we're formatting directly to stdout
- It's not true formatting: it mainly just builds a nice representation of the internal structure of
an object and its subobjects, but it can't really mix and match that representation with anything
- It's only customizable on a very shallow level (indent size); stuff like colorization, multiline /
not multiline, maximum length before abbreviation, etc. is all not configurable
## Task
Re-write `core::format` to satisfy the following requirements:
- It must only allocate memory if the result is going to be stored in memory; if it is writing to a
file or a socket or some other data sink, the formatting result should go directly to that
destination
- It should support interpolating the format results into static strings (while upholding the
no-allocation requirement above)
- It should not use `std::string`; instead, the output should be written as UTF-8 into a
`String<Utf8>` (or at least a `DynamicArray<char8_t>`)
- It should support customization at the point of the format call (probably through some kind of
format specifier syntax like you see in `std::printf()`)
The most likely best implementation for this type of system will be passing a mutable reference to
some kind of "sink" structure down through the `format()` methods of each subobject, allowing each
to write its information to the sink. That means that `format()` will no longer return anything,
instead leaving the sink to compose the parts or just write them as is.