Skip to content

Commit 9a43056

Browse files
authored
Add interface IFormattingExtensionsToggle to skip formatting (#436)
1 parent a2a4969 commit 9a43056

File tree

8 files changed

+86
-7
lines changed

8 files changed

+86
-7
lines changed

src/SmartFormat.Tests/Extensions/DefaultSourceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ public void Call_With_Numeric_Placeholder_Should_Succeed()
3131
Assert.That(code:() => { result = smart.Format("{0}", 999); }, Throws.Nothing);
3232
Assert.That(result, Is.EqualTo("999"));
3333
}
34-
}
34+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using NUnit.Framework;
2+
using SmartFormat.Core.Extensions;
3+
using SmartFormat.Core.Formatting;
4+
using SmartFormat.Extensions;
5+
6+
namespace SmartFormat.Tests.Extensions;
7+
8+
[TestFixture]
9+
public class NoFormattingSourceTests
10+
{
11+
[Test]
12+
public void Use_of_ToggleFormattingExtensions()
13+
{
14+
var smart = new SmartFormatter();
15+
smart.AddExtensions(new NoFormattingSource());
16+
smart.AddExtensions(new DefaultFormatter());
17+
18+
Assert.That(smart.Format("{0}", 999), Is.EqualTo("No formatting"));
19+
}
20+
21+
public class NoFormattingSource : ISource
22+
{
23+
public bool TryEvaluateSelector(ISelectorInfo selectorInfo)
24+
{
25+
// Split test for IFormattingExtensionsToggle and FormattingInfo
26+
// for clarity. This is not necessary in production code.
27+
28+
// Disable all formatting extensions
29+
if (selectorInfo is IFormattingExtensionsToggle toggle)
30+
{
31+
toggle.DisableFormattingExtensions = true;
32+
}
33+
34+
if (selectorInfo is FormattingInfo fi)
35+
{
36+
// Write a note or result directly to the output
37+
fi.Write("No formatting");
38+
}
39+
40+
selectorInfo.Result = selectorInfo.CurrentValue;
41+
return true;
42+
}
43+
}
44+
}

src/SmartFormat.Tests/Extensions/ValueTupleSourceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,6 @@ private class PureSelectorInfo : ISelectorInfo
131131
public string SelectorOperator { get; } = string.Empty;
132132
public object? Result { get; set; }
133133
public Placeholder? Placeholder { get; }
134-
public FormatDetails FormatDetails { get; } = (FormatDetails) null!; // dummy
134+
public FormatDetails FormatDetails { get; } = null!; // dummy
135135
}
136136
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Copyright SmartFormat Project maintainers and contributors.
3+
// Licensed under the MIT license.
4+
5+
using System;
6+
7+
namespace SmartFormat.Core.Extensions;
8+
9+
/// <summary>
10+
/// Represents a toggle for enabling or disabling <see cref="IFormatter"/> extensions.
11+
/// This interface is primarily used by <see cref="ISource"/> extensions
12+
/// that receive it as part of the <see cref="ISelectorInfo"/> parameter.
13+
/// </summary>
14+
public interface IFormattingExtensionsToggle
15+
{
16+
// This interface should become part of ISelectorInfo in the future.
17+
18+
/// <summary>
19+
/// Gets or sets a value indicating whether the <see cref="IFormatter"/> extensions are enabled.
20+
/// The value should be <see langword="false"/> (default), unless the <see cref="ISource"/> extension
21+
/// found a value in <seealso cref="ISource.TryEvaluateSelector"/> where default formatting cannot reasonably be done.
22+
/// <br/>
23+
/// In this case the <see cref="ISource"/> may directly write some output using <see cref="IFormattingInfo.Write(ReadOnlySpan{char})"/>,
24+
/// or produce no output at all.
25+
/// </summary>
26+
public bool DisableFormattingExtensions { get; set; }
27+
}

src/SmartFormat/Core/Extensions/ISource.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright SmartFormat Project maintainers and contributors.
33
// Licensed under the MIT license.
44

5+
using SmartFormat.Core.Formatting;
56
using SmartFormat.Core.Parsing;
67

78
namespace SmartFormat.Core.Extensions;
@@ -14,7 +15,8 @@ public interface ISource
1415
/// <summary>
1516
/// Evaluates the <see cref="Selector" /> based on the <see cref="ISelectorInfo.CurrentValue" />.
1617
/// </summary>
17-
/// <param name="selectorInfo"></param>
18+
/// <param name="selectorInfo">The information about the selector being evaluated.<br/>
19+
/// Note: This can be casted to <seealso cref="FormattingInfo"/>, which also implements <seealso cref="IFormattingExtensionsToggle"/>.</param>
1820
/// <returns>If the <see cref="Selector"/> could be evaluated,
1921
/// the <see cref="ISelectorInfo.Result" /> will be set and <see langword="true"/> will be returned.
2022
/// </returns>

src/SmartFormat/Core/Formatting/FormattingInfo.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// Licensed under the MIT license.
44

55
using System;
6-
using System.Buffers;
76
using System.Collections.Generic;
87
using SmartFormat.Core.Extensions;
98
using SmartFormat.Core.Output;
@@ -17,7 +16,7 @@ namespace SmartFormat.Core.Formatting;
1716
/// <summary>
1817
/// The class contains the fields and methods which are necessary for formatting.
1918
/// </summary>
20-
public class FormattingInfo : IFormattingInfo, ISelectorInfo
19+
public class FormattingInfo : IFormattingInfo, ISelectorInfo, IFormattingExtensionsToggle
2120
{
2221
/// <summary>
2322
/// CTOR for object pooling.
@@ -52,6 +51,7 @@ public FormattingInfo Initialize(FormattingInfo? parent, FormatDetails formatDet
5251
CurrentValue = currentValue;
5352
FormatDetails = formatDetails;
5453
Format = format;
54+
DisableFormattingExtensions = false;
5555
// inherit alignment
5656
if (parent != null) Alignment = parent.Alignment;
5757
else if (format.ParentPlaceholder != null) Alignment = format.ParentPlaceholder.Alignment;
@@ -73,6 +73,7 @@ public FormattingInfo Initialize(FormattingInfo? parent, FormatDetails formatDet
7373
FormatDetails = formatDetails;
7474
Placeholder = placeholder;
7575
Format = placeholder.Format;
76+
DisableFormattingExtensions = false;
7677
CurrentValue = currentValue;
7778
// inherit alignment
7879
Alignment = placeholder.Alignment;
@@ -94,6 +95,7 @@ public void ReturnToPool()
9495
Alignment = 0;
9596

9697
Format = null;
98+
DisableFormattingExtensions = false;
9799
CurrentValue = null;
98100

99101
// Children can safely be returned
@@ -304,6 +306,9 @@ public FormattingException FormattingException(string issue, FormatItem? problem
304306
/// </summary>
305307
public object? Result { get; set; }
306308

309+
/// <inheritdoc />
310+
public bool DisableFormattingExtensions { get; set; }
311+
307312
/// <summary>
308313
/// Creates a child <see cref="FormattingInfo"/> from the current <see cref="FormattingInfo"/> instance for a <see cref="Parsing.Format"/>.
309314
/// </summary>

src/SmartFormat/Core/Formatting/ISelectorInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public interface ISelectorInfo
2929
string SelectorText { get; }
3030

3131
/// <summary>
32-
/// The index of the selector in a multi-part selector.
32+
/// The index of the selector in a multipart selector.
3333
/// Example: {Person.Birthday.Year} has 3 selectors,
3434
/// and Year has a SelectorIndex of 2.
3535
/// </summary>

src/SmartFormat/Evaluator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System;
77
using SmartFormat.Core.Extensions;
88
using SmartFormat.Core.Formatting;
9-
using SmartFormat.Core.Output;
109
using SmartFormat.Core.Parsing;
1110
using SmartFormat.Core.Settings;
1211
using SmartFormat.Pooling.SmartPools;
@@ -225,6 +224,8 @@ private bool SkipThisSelector(Selector selector)
225224
/// <exception cref="FormattingException"></exception>
226225
private void InvokeFormatters(FormattingInfo formattingInfo)
227226
{
227+
if (formattingInfo.DisableFormattingExtensions) return;
228+
228229
var placeholder = formattingInfo.Placeholder!;
229230

230231
try

0 commit comments

Comments
 (0)