-
-
Notifications
You must be signed in to change notification settings - Fork 3
Formatters
The Formatter
class provides a way to control exactly what characters are written when serializing a cell of a particular type. Formatters are used in both static and dynamic serialization - in static serialization a Formatter
is specified for an entire column, while in dynamic serialization the Formatter
can vary per-cell.
There are a number of Default Formatters provided by Cesil, which may be adequate for your needs. They can be obtained with Formatter.GetDefault(TypeInfo)
.
Formatter
instances can be backed by methods and delegates. Both return a bool
value where true
indicates success and false
indicates failure. If a delegate or method fails and a fallback has been configured with Else(Formatter)
the fallback will be tried.
Any delegate of the form bool Name(FormattingType, in WriteContext, IBufferWriter<char>)
can back a Formatter
.
Cesil provides FormatterDelegate<TValue>
and Formatter.ForDelegate<TValue>(FormatterDelegate<TValue>)
which conform to this form. You can also explicitly cast any delegate to Formatter
, provided it is logically equivalent to FormatterDelegate<TValue>
.
If a delegate backed Formatter
returns false
, the Formatter
configured by Else(Formatter)
(if any) will be tried next.
Any static MethodInfo
that exposes the same interface as FormatterDelegate<TValue>
can back a Formatter
.
Concretely, the method must:
- be static
- return a
bool
- have 3 parameters
- The first parameter can be any type
- The second parameter must be
in WriteContext
- The third parameter must be
IBufferWriter<char>
If a method backed Formatter
returns false
, the Formatter
configured by Else(Formatter)
(if any) will be tried next.
Cesil provides a number of Default Formatters, obtainable with Formatter.GetDefault(TypeInfo)
.
These Formatters
all correctly report failure, and thus support chaining.
Formatters
can fail, indicated by it's backer returning false
. If Cesil cannot format a value, an exception will be raised.
To try another Formatter
after one fails, you chain them with the Else(Formatter)
method. Else(Formatter)
specifies which Formatter
to try if the current one fails.
In order to support this behavior, a failing Formatter
must not write to the IBufferWriter<char>
. Requesting a Span<char>
or Memory<char>
does not count as a write, Advance(int)
"commits" to writing. Be aware of helper methods that call Advance(int)
internally, as they may write even in a failure case.
Else(Formatter)
returns a new Formatter
, the original is not modified.
If a Formatter
already has a fallback Formatter
specified, the one passed to Else(Formatter)
will be tried after all the others have failed. Conceptually, Else(Formatter)
adds a Formatter
to the end of a list of fallbacks to try.
Cesil provides explicit casts of MethodInfo
, and Delegate
to Formatter
. These are roughly equivalent to calling the static ForXXX(...)
methods on Formatter
, but differ by allowing null
values.