axuno / SmartFormat

A lightweight text templating library written in C# which can be a drop-in replacement for string.Format
Other
1.1k stars 105 forks source link

ConditionalFormatter should throw on nested Format arguments, not just ignore #250

Closed axunonb closed 2 years ago

axunonb commented 2 years ago

Discussed in https://github.com/axuno/SmartFormat/discussions/249

Originally posted by **mhspelt** February 25, 2022 Hi, is it possible to use _cond_ or _choose_ to check whether two values are the same? I tried the following but it does not work: ``` var data = new { x = 3, y = 3 }; // Print "is on the line" iff data.x == data.y: Console.WriteLine(Smart.Format("The point ({x}, {y}) {x:choose({y}):is|is not} on the line y = x", data)); Console.WriteLine(Smart.Format("The point ({x}, {y}) {x:cond:={y}?is|is not} on the line y = x", data)); ``` It seems that `{y}` is not getting substituted before the choose or cond is evaluated. Would be great if there is a standard way to do it that I've been missing. Fiddle: https://dotnetfiddle.net/08nHRw
axunonb commented 2 years ago

Throughout all IFormatters, Placeholders are only used to output values. Changing this principle would have quite an impact. E.g.: Placeholders use a value, that can also be formatted. So should the original or the formatted value be used? How to deal with complex types?

var data = new { 
    x = 3,
    y = 3,
};

// This DOES WORK - placeholders are not evaluated yet when comparing       
Console.WriteLine(Smart.Format("The point ({x}, {y}) {x:choose({y}):is|is not} on the line y = x", data));
Console.WriteLine(Smart.Format("The point ({x}, {y}) {x:cond:={y}?is|is not} on the line y = x", data));

// This is a workaround with minimal effort and an easily understandable format string:
Console.WriteLine(Smart.Format("The point ({x}, {y}) {1:choose(True):is|is not} on the line y = x", data, data.x == data.y));
Console.WriteLine(Smart.Format("The point ({x}, {y}) {1:cond:is|is not} on the line y = x", data, data.x == data.y));