ITemplateBreakdown
ITemplateBreakdown is a breakdown of template string into text and placeholder parts.
/// <summary>Template string breakdown into parts, e.g. "Welcome, {0}!", into text and placeholder parts. </summary>
public interface ITemplateBreakdown : ITemplateText
{
/// <summary>Breakdown into sequence of text and placeholder parts.</summary>
ITemplatePart[] Parts { get; set; }
/// <summary>Placeholders in order of occurance in <see cref="ITemplateText.Text"/>.</summary>
ITemplatePlaceholderPart[] Placeholders { get; set; }
/// <summary>Parameters in order of arguments and <see cref="ITemplateParameterPart.ParameterIndex"/>.</summary>
ITemplateParameterPart?[] Parameters { get; set; }
}
TemplateBreakdown is the default implementation. Breakdown is composed of parts that describe string segments.
// Create format string
string text = "Welcome, {user}";
ReadOnlyMemory<char> mem = text.AsMemory();
TemplateBreakdown breakdown = new TemplateBreakdown { Text = text };
var textPart = new TemplateTextPart().SetBreakdown(breakdown).SetTexts(mem[..9], Escaper.Brace);
var parameter = new TemplateParameterPart().SetBreakdown(breakdown).SetTexts(mem[10..14]);
var placeholder = new TemplatePlaceholderPart().SetBreakdown(breakdown).SetTexts(mem[9..15]).SetParameter(parameter);
breakdown.Parts = new ITemplatePart[] { textPart, placeholder };
breakdown.SetReadOnly();
// Print
WriteLine(breakdown.Print(CultureInfo.InvariantCulture, new object?[] { "Donald Duck" }));
ITemplateFormat.Breakdown[string] parses string into breakdown using the rules of the template format.
ITemplateBreakdown breakdown1 = TemplateFormat.BraceNumeric.Breakdown["Welcome, {0}"];
ITemplateBreakdown breakdown2 = TemplateFormat.BraceAlphaNumeric.Breakdown["Welcome, {user}"];
.Print(cultureInfo, arguments) puts arguments in placeholder locations.
ITemplateBreakdown breakdown = TemplateFormat.BraceAlphaNumeric.Breakdown["Welcome, {user}"];
WriteLine(breakdown.Print(CultureInfo.InvariantCulture, new object?[] { "Donald Duck" })); // "Welcome, Donald Duck"
Parse errors are readable from ITemplateMalformedPart.
ITemplateBreakdown breakdown = TemplateFormat.BraceAlphaNumeric.Breakdown["Welcome, {}"];
// Get malformed parts
foreach ((int index, int length, ReadOnlyMemory<char>? malformed) in breakdown.MalformedParts())
{
// Write
WriteLine($"Malformed '{malformed}' at: {index}:{index + length}"); // Malformed at: 9:11
}
Parameter index can be used multiple times in different placeholder locations.
// Create breakdown
ITemplateBreakdown breakdown = TemplateFormat.Brace.Breakdown["Error code: {0} (0x{0:X4})."];
// "Error code: 256 (0x0100)."
WriteLine(breakdown.Print(null, new object?[] { 0x100 }));
// Placeholder: "{0}", Placeholder: "{0:X8}"
WriteLine(string.Join(", ", (IEnumerable<ITemplatePlaceholderPart>)breakdown.Placeholders));
// Parameter: "0"
WriteLine(string.Join(", ", (IEnumerable<ITemplateParameterPart>)breakdown.Parameters));
As can parameter name.
// Create breakdown
ITemplateBreakdown breakdown = TemplateFormat.Brace.Breakdown["Error code: {code} (0x{code:X4})."];
// "Error code: 256 (0x0100)."
WriteLine(breakdown.Print(null, new object?[] { 0x100 }));
// Placeholder: "{code}", Placeholder: "{code:X4}"
WriteLine(string.Join(", ", (IEnumerable<ITemplatePlaceholderPart>)breakdown.Placeholders));
// Parameter: "code"
WriteLine(string.Join(", ", (IEnumerable<ITemplateParameterPart>)breakdown.Parameters));
ITemplatePart
ITemplatePart is a set of interfaces that describe template parts. These can be extended in 3rd party libraries.
/// <summary>A part of a <see cref="ITemplateBreakdown"/>.</summary>
public interface ITemplatePart
{
/// <summary>Reference to breakdown root</summary>
ITemplateBreakdown? TemplateBreakdown { get; set; }
/// <summary>Escaped text that is a slice of <see cref="ITemplateText.Text"/>.</summary>
ReadOnlyMemory<char> Escaped { get; set; }
/// <summary>Unescaped text that is either exact same slice than <see cref="Escaped"/>, or its derived unescape.</summary>
ReadOnlyMemory<char> Unescaped { get; set; }
}
/// <summary>Text part.</summary>
public interface ITemplateTextPart : ITemplatePart { }
/// <summary>A placeholder part of <see cref="ITemplateBreakdown"/>.</summary>
public interface ITemplatePlaceholderPart : ITemplatePart
{
/// <summary>Parameter name or number, e.g. "object" or "0"</summary>
ITemplateParameterPart Parameter { get; set; }
/// <summary>Formatting descriptions, e.g. ",10:N0" or ":X8".</summary>
ITemplateFormattingPart? Formatting { get; set; }
/// <summary>Alignment describes padding.</summary>
ITemplateAlignmentPart? Alignment { get; set; }
}
/// <summary>Parameter name or index number part</summary>
public interface ITemplateParameterPart : ITemplatePart
{
/// <summary>Parameter index in order of arguments and <see cref="ITemplateBreakdown.Parameters"/>.</summary>
int ParameterIndex { get; set; }
}
/// <summary>Alignment describes padding.</summary>
public interface ITemplateAlignmentPart : ITemplatePart
{
/// <summary>Alignment, with positive value, padding goes on left side, with negative to right side.</summary>
int Alignment { get; set; }
}
/// <summary>Formatting description, e.g. ",10:N0" or ":X8".</summary>
public interface ITemplateFormattingPart : ITemplatePart { }
/// <summary>Malformed part</summary>
public interface ITemplateMalformedPart : ITemplatePart { }
Full Example
Full example
using System.Globalization;
using Avalanche.Template;
using Avalanche.Utilities;
using static System.Console;
public class templatebreakdown
{
public static void Run()
{
{
// <01>
// Create format string
string text = "Welcome, {user}";
ReadOnlyMemory<char> mem = text.AsMemory();
TemplateBreakdown breakdown = new TemplateBreakdown { Text = text };
var textPart = new TemplateTextPart().SetBreakdown(breakdown).SetTexts(mem[..9], Escaper.Brace);
var parameter = new TemplateParameterPart().SetBreakdown(breakdown).SetTexts(mem[10..14]);
var placeholder = new TemplatePlaceholderPart().SetBreakdown(breakdown).SetTexts(mem[9..15]).SetParameter(parameter);
breakdown.Parts = new ITemplatePart[] { textPart, placeholder };
breakdown.SetReadOnly();
// Print
WriteLine(breakdown.Print(CultureInfo.InvariantCulture, new object?[] { "Donald Duck" }));
// </01>
WriteLine(textPart.Unescaped);
WriteLine(TemplateFormat.BraceNumeric.Assemble[breakdown]);
}
{
// <04>
ITemplateBreakdown breakdown1 = TemplateFormat.BraceNumeric.Breakdown["Welcome, {0}"];
ITemplateBreakdown breakdown2 = TemplateFormat.BraceAlphaNumeric.Breakdown["Welcome, {user}"];
// </04>
}
{
// <08>
ITemplateBreakdown breakdown = TemplateFormat.BraceAlphaNumeric.Breakdown["Welcome, {user}"];
WriteLine(breakdown.Print(CultureInfo.InvariantCulture, new object?[] { "Donald Duck" })); // "Welcome, Donald Duck"
// </08>
}
{
// <10>
ITemplateBreakdown breakdown = TemplateFormat.BraceAlphaNumeric.Breakdown["Welcome, {}"];
// Get malformed parts
foreach ((int index, int length, ReadOnlyMemory<char>? malformed) in breakdown.MalformedParts())
{
// Write
WriteLine($"Malformed '{malformed}' at: {index}:{index + length}"); // Malformed at: 9:11
}
// </10>
}
{
// <13>
// Create breakdown
ITemplateBreakdown breakdown = TemplateFormat.Brace.Breakdown["Error code: {0} (0x{0:X4})."];
// "Error code: 256 (0x0100)."
WriteLine(breakdown.Print(null, new object?[] { 0x100 }));
// Placeholder: "{0}", Placeholder: "{0:X8}"
WriteLine(string.Join(", ", (IEnumerable<ITemplatePlaceholderPart>)breakdown.Placeholders));
// Parameter: "0"
WriteLine(string.Join(", ", (IEnumerable<ITemplateParameterPart>)breakdown.Parameters));
// </13>
WriteLine(TemplateFormat.BraceAlphaNumeric.Assemble[breakdown]);
WriteLine(TemplateFormat.BraceNumeric.Assemble[breakdown]);
}
{
// <14>
// Create breakdown
ITemplateBreakdown breakdown = TemplateFormat.Brace.Breakdown["Error code: {code} (0x{code:X4})."];
// "Error code: 256 (0x0100)."
WriteLine(breakdown.Print(null, new object?[] { 0x100 }));
// Placeholder: "{code}", Placeholder: "{code:X4}"
WriteLine(string.Join(", ", (IEnumerable<ITemplatePlaceholderPart>)breakdown.Placeholders));
// Parameter: "code"
WriteLine(string.Join(", ", (IEnumerable<ITemplateParameterPart>)breakdown.Parameters));
// </14>
WriteLine(TemplateFormat.BraceAlphaNumeric.Assemble[breakdown]);
WriteLine(TemplateFormat.BraceNumeric.Assemble[breakdown]);
}
}
}