fix(opl): only apply the ':#' cliloc marker to integer values

The IPropertyList interpolation handler treated any {value:#} as a cliloc marker
(emit '#<value>'). But cliloc numbers are integers; a float/double/decimal with '#'
is the standard custom-numeric (digit-placeholder) format, not a cliloc reference.
Gate the marker on an integer value type so float/double/decimal {x:#} formats
normally, narrowing the ambiguity to the harmless {0:#} integer case ('#0').

Adds ObjectPropertyListSpanAddTests.HashFormat_OnlyMarksIntegers: int {value:#}
emits '#<value>'; double {value:#} uses the standard '#' format (no leading '#').

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kamron Batman 2026-07-19 10:39:49 -07:00
parent 8d88ef70fd
commit bcb1da47eb
2 changed files with 18 additions and 3 deletions

View file

@ -62,6 +62,21 @@ public class ObjectPropertyListSpanAddTests
Assert.Equal((1070722, "Custom"), entries[0]);
}
[Fact]
public void HashFormat_OnlyMarksIntegers()
{
// Integer {value:#} emits the cliloc marker "#<value>".
var intList = new ObjectPropertyList(null);
intList.Add(1062028, $"{1043009:#}");
Assert.Equal((1062028, "#1043009"), Decode(intList)[0]);
// Float {value:#} is the standard '#' custom-numeric (digit-placeholder) format, not a cliloc
// marker -- so no leading '#'.
var dblList = new ObjectPropertyList(null);
dblList.Add(1062028, $"{42.0:#}");
Assert.Equal((1062028, 42.0.ToString("#")), Decode(dblList)[0]); // "42"
}
[Fact]
public void Add_TruncatesArgumentOverMaxLength()
{

View file

@ -384,9 +384,9 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable
public void AppendFormatted<T>(T value, string? format)
{
// We support localization '#' cliloc formatter for custom property lists
// This allows someone to build an IPropertyList that creates HTML using the same syntax as LocalizationInterpolationHandler
if (format == "#")
// '#' marks an integer argument as a cliloc ("#<value>"). Integers only -- a float/double/decimal
// '#' is the standard numeric format, not a cliloc marker.
if (format == "#" && value is int or uint or long or ulong or short or ushort or byte or sbyte)
{
AppendLiteral("#");
format = null;