Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add interface IFormattingExtensionsToggle to skip formatting #436

Merged
merged 1 commit into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add interface IFormattingExtensionsToggle to skip formatting
  • Loading branch information
axunonb committed Jul 29, 2024
commit db7a6d113d9312173c4b91beb04f496a18fd783b
2 changes: 1 addition & 1 deletion src/SmartFormat.Tests/Extensions/DefaultSourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ public void Call_With_Numeric_Placeholder_Should_Succeed()
Assert.That(code:() => { result = smart.Format("{0}", 999); }, Throws.Nothing);
Assert.That(result, Is.EqualTo("999"));
}
}
}
44 changes: 44 additions & 0 deletions src/SmartFormat.Tests/Extensions/NoFormattingSourceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using NUnit.Framework;
using SmartFormat.Core.Extensions;
using SmartFormat.Core.Formatting;
using SmartFormat.Extensions;

namespace SmartFormat.Tests.Extensions;

[TestFixture]
public class NoFormattingSourceTests
{
[Test]
public void Use_of_ToggleFormattingExtensions()
{
var smart = new SmartFormatter();
smart.AddExtensions(new NoFormattingSource());
smart.AddExtensions(new DefaultFormatter());

Assert.That(smart.Format("{0}", 999), Is.EqualTo("No formatting"));
}

public class NoFormattingSource : ISource
{
public bool TryEvaluateSelector(ISelectorInfo selectorInfo)
{
// Split test for IFormattingExtensionsToggle and FormattingInfo
// for clarity. This is not necessary in production code.

// Disable all formatting extensions
if (selectorInfo is IFormattingExtensionsToggle toggle)
{
toggle.DisableFormattingExtensions = true;
}

if (selectorInfo is FormattingInfo fi)
{
// Write a note or result directly to the output
fi.Write("No formatting");
}

selectorInfo.Result = selectorInfo.CurrentValue;
return true;
}
}
}
2 changes: 1 addition & 1 deletion src/SmartFormat.Tests/Extensions/ValueTupleSourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,6 @@ private class PureSelectorInfo : ISelectorInfo
public string SelectorOperator { get; } = string.Empty;
public object? Result { get; set; }
public Placeholder? Placeholder { get; }
public FormatDetails FormatDetails { get; } = (FormatDetails) null!; // dummy
public FormatDetails FormatDetails { get; } = null!; // dummy
}
}
27 changes: 27 additions & 0 deletions src/SmartFormat/Core/Extensions/IFormattingExtensionsToggler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Copyright SmartFormat Project maintainers and contributors.
// Licensed under the MIT license.

using System;

namespace SmartFormat.Core.Extensions;

/// <summary>
/// Represents a toggle for enabling or disabling <see cref="IFormatter"/> extensions.
/// This interface is primarily used by <see cref="ISource"/> extensions
/// that receive it as part of the <see cref="ISelectorInfo"/> parameter.
/// </summary>
public interface IFormattingExtensionsToggle
{
// This interface should become part of ISelectorInfo in the future.

/// <summary>
/// Gets or sets a value indicating whether the <see cref="IFormatter"/> extensions are enabled.
/// The value should be <see langword="false"/> (default), unless the <see cref="ISource"/> extension
/// found a value in <seealso cref="ISource.TryEvaluateSelector"/> where default formatting cannot reasonably be done.
/// <br/>
/// In this case the <see cref="ISource"/> may directly write some output using <see cref="IFormattingInfo.Write(ReadOnlySpan{char})"/>,
/// or produce no output at all.
/// </summary>
public bool DisableFormattingExtensions { get; set; }
}
4 changes: 3 additions & 1 deletion src/SmartFormat/Core/Extensions/ISource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright SmartFormat Project maintainers and contributors.
// Licensed under the MIT license.

using SmartFormat.Core.Formatting;
using SmartFormat.Core.Parsing;

namespace SmartFormat.Core.Extensions;
Expand All @@ -14,7 +15,8 @@ public interface ISource
/// <summary>
/// Evaluates the <see cref="Selector" /> based on the <see cref="ISelectorInfo.CurrentValue" />.
/// </summary>
/// <param name="selectorInfo"></param>
/// <param name="selectorInfo">The information about the selector being evaluated.<br/>
/// Note: This can be casted to <seealso cref="FormattingInfo"/>, which also implements <seealso cref="IFormattingExtensionsToggle"/>.</param>
/// <returns>If the <see cref="Selector"/> could be evaluated,
/// the <see cref="ISelectorInfo.Result" /> will be set and <see langword="true"/> will be returned.
/// </returns>
Expand Down
9 changes: 7 additions & 2 deletions src/SmartFormat/Core/Formatting/FormattingInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Licensed under the MIT license.

using System;
using System.Buffers;
using System.Collections.Generic;
using SmartFormat.Core.Extensions;
using SmartFormat.Core.Output;
Expand All @@ -17,7 +16,7 @@ namespace SmartFormat.Core.Formatting;
/// <summary>
/// The class contains the fields and methods which are necessary for formatting.
/// </summary>
public class FormattingInfo : IFormattingInfo, ISelectorInfo
public class FormattingInfo : IFormattingInfo, ISelectorInfo, IFormattingExtensionsToggle
{
/// <summary>
/// CTOR for object pooling.
Expand Down Expand Up @@ -52,6 +51,7 @@ public FormattingInfo Initialize(FormattingInfo? parent, FormatDetails formatDet
CurrentValue = currentValue;
FormatDetails = formatDetails;
Format = format;
DisableFormattingExtensions = false;
// inherit alignment
if (parent != null) Alignment = parent.Alignment;
else if (format.ParentPlaceholder != null) Alignment = format.ParentPlaceholder.Alignment;
Expand All @@ -73,6 +73,7 @@ public FormattingInfo Initialize(FormattingInfo? parent, FormatDetails formatDet
FormatDetails = formatDetails;
Placeholder = placeholder;
Format = placeholder.Format;
DisableFormattingExtensions = false;
CurrentValue = currentValue;
// inherit alignment
Alignment = placeholder.Alignment;
Expand All @@ -94,6 +95,7 @@ public void ReturnToPool()
Alignment = 0;

Format = null;
DisableFormattingExtensions = false;
CurrentValue = null;

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

/// <inheritdoc />
public bool DisableFormattingExtensions { get; set; }

/// <summary>
/// Creates a child <see cref="FormattingInfo"/> from the current <see cref="FormattingInfo"/> instance for a <see cref="Parsing.Format"/>.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/SmartFormat/Core/Formatting/ISelectorInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface ISelectorInfo
string SelectorText { get; }

/// <summary>
/// The index of the selector in a multi-part selector.
/// The index of the selector in a multipart selector.
/// Example: {Person.Birthday.Year} has 3 selectors,
/// and Year has a SelectorIndex of 2.
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion src/SmartFormat/Evaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System;
using SmartFormat.Core.Extensions;
using SmartFormat.Core.Formatting;
using SmartFormat.Core.Output;
using SmartFormat.Core.Parsing;
using SmartFormat.Core.Settings;
using SmartFormat.Pooling.SmartPools;
Expand Down Expand Up @@ -225,6 +224,8 @@ private bool SkipThisSelector(Selector selector)
/// <exception cref="FormattingException"></exception>
private void InvokeFormatters(FormattingInfo formattingInfo)
{
if (formattingInfo.DisableFormattingExtensions) return;

var placeholder = formattingInfo.Placeholder!;

try
Expand Down