Skip to content

Commit

Permalink
Replaced FormatCache by Format (axuno#183)
Browse files Browse the repository at this point in the history
The class `FormatCache` is replaced by `Format`. `Format` stores the result from the `Parser` parsing the input string. The `SmartFormatter` has additional overloads for using the cached `Format` as an argument, instead of an additional wrapper around `Format`.
axunonb authored Jul 24, 2021
1 parent 9cfcf19 commit 7c84733
Showing 7 changed files with 76 additions and 115 deletions.
16 changes: 16 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,22 @@ v3.0.0-alpha.1

### Current changes merged into the `version/v3.0` branch:

#### `Format` replaces `FormatCache`

In v2.x the `FormatCache` class had a `CachedObjects` property, which was not implemented:
```Csharp
public class FormatCache
{
public FormatCache(Format format)
{ Format = format; }
public Format Format { get; }
public Dictionary<string, object> CachedObjects { get; } = new Dictionary<string, object>();
}
```
The class `FormatCache` is now replaced by `Format`. `Format` stores the result from the `Parser` parsing the input string. The `SmartFormatter` has additional overloads for using the cached `Format` as an argument, instead of an additional wrapper around `Format`.

It is **highly recommended** to use these `SmartFormatter` methods whenever there is a **constant input string** with **different data arguments**.

#### Bugfix for plural rule ([#182](https://github.com/axuno/SmartFormat/pull/182))
* Fixes #179 (DualFromZeroToTwo plural rule). Thanks to @OhSoGood

18 changes: 2 additions & 16 deletions src/SmartFormat.Tests/Core/FormatCacheTests.cs
Original file line number Diff line number Diff line change
@@ -18,27 +18,14 @@ private SmartFormatter GetSimpleFormatter()
return formatter;
}

[Test]
public void Create_Cache()
{
var sf = new SmartFormatter();
var format = new Format(sf.Settings, "the base string");
var fc = new FormatCache(format);
Assert.AreEqual(format, fc.Format);
Assert.IsAssignableFrom<Dictionary<string,object>>(fc.CachedObjects);
fc.CachedObjects.Add("key", "value");
Assert.IsTrue(fc.CachedObjects["key"].ToString() == "value");
}

[Test]
public void Format_WithCache()
{
var data = new {Name = "Joe", City = "Melbourne"};
var formatter = GetSimpleFormatter();
var formatString = "{Name}, {City}";
var format = formatter.Parser.ParseFormat(formatString);
var cache = new FormatCache(format);
Assert.That(formatter.FormatWithCache(ref cache, formatString, data), Is.EqualTo($"{data.Name}, {data.City}"));
Assert.That(formatter.Format(format, data), Is.EqualTo($"{data.Name}, {data.City}"));
}

[Test]
@@ -48,9 +35,8 @@ public void Format_WithCache_Into()
var formatter = GetSimpleFormatter();
var formatString = "{Name}, {City}";
var format = formatter.Parser.ParseFormat(formatString);
var cache = new FormatCache(format);
var output = new StringOutput();
formatter.FormatWithCacheInto(ref cache, output, formatString, data);
formatter.FormatInto(output, format, data);
Assert.That(output.ToString(), Is.EqualTo($"{data.Name}, {data.City}"));
}
}
3 changes: 1 addition & 2 deletions src/SmartFormat.Tests/Core/FormatterTests.cs
Original file line number Diff line number Diff line change
@@ -174,12 +174,11 @@ public void SmartFormatter_FormatDetails()
formatter.Settings.Formatter.ErrorAction = FormatErrorAction.OutputErrorInResult;
formatter.Settings.Parser.ErrorAction = ParseErrorAction.OutputErrorInResult;
var formatParsed = formatter.Parser.ParseFormat(format);
var formatDetails = new FormatDetails(formatter, formatParsed, args, null, null, output);
var formatDetails = new FormatDetails(formatter, formatParsed, args, null, output);

Assert.AreEqual(args, formatDetails.OriginalArgs);
Assert.AreEqual(format, formatDetails.OriginalFormat.RawText);
Assert.AreEqual(formatter.Settings, formatDetails.Settings);
Assert.IsTrue(formatDetails.FormatCache == null);
}

[Test]
38 changes: 0 additions & 38 deletions src/SmartFormat/Core/Formatting/FormatCache.cs

This file was deleted.

14 changes: 3 additions & 11 deletions src/SmartFormat/Core/Formatting/FormatDetails.cs
Original file line number Diff line number Diff line change
@@ -21,18 +21,16 @@ public class FormatDetails
/// Creates a new instance of <see cref="FormatDetails"/>
/// </summary>
/// <param name="formatter"></param>
/// <param name="originalFormat">The the original <see cref="Format"/> returned by the <see cref="Parser"/> or a <see cref="Formatting.FormatCache"/>.</param>
/// <param name="originalFormat">The the original <see cref="Format"/> returned by the <see cref="Parser"/>.</param>
/// <param name="originalArgs">The original set of arguments passed to the format method.</param>
/// <param name="formatCache">This to cache resources between formatting calls.</param>
/// <param name="provider">The <see cref="IFormatProvider"/> that can be used to determine how to format items.</param>
/// <param name="output">The <see cref="IOutput"/> where the result is written.</param>
public FormatDetails(SmartFormatter formatter, Format originalFormat, IList<object> originalArgs,
FormatCache? formatCache, IFormatProvider? provider, IOutput output)
IFormatProvider? provider, IOutput output)
{
Formatter = formatter;
OriginalFormat = originalFormat;
OriginalArgs = originalArgs;
FormatCache = formatCache;
Provider = provider;
Output = output;
}
@@ -44,7 +42,7 @@ public FormatDetails(SmartFormatter formatter, Format originalFormat, IList<obje
public SmartFormatter Formatter { get; }

/// <summary>
/// Gets the <see cref="Format"/> returned by the <see cref="Parser"/> or which is coming from <see cref="Formatting.FormatCache"/>.
/// Gets the <see cref="Format"/> returned by the <see cref="Parser"/>.
/// </summary>
public Format OriginalFormat { get; }

@@ -54,12 +52,6 @@ public FormatDetails(SmartFormatter formatter, Format originalFormat, IList<obje
/// </summary>
public IList<object> OriginalArgs { get; }

/// <summary>
/// This object can be used to cache resources between formatting calls.
/// It will be null unless FormatWithCache is called.
/// </summary>
public FormatCache? FormatCache { get; }

/// <summary>
/// The <see cref="IFormatProvider"/> that can be used to determine how to
/// format items such as numbers, dates, and anything else that
13 changes: 0 additions & 13 deletions src/SmartFormat/SmartExtensions.cs
Original file line number Diff line number Diff line change
@@ -73,19 +73,6 @@ public static string FormatSmart(this string format, params object[] args)
return Smart.Format(format, args);
}

/// <summary>
/// Formats the specified arguments using this string as a template.
/// Caches the parsing results for increased performance.
/// </summary>
/// <param name="format">The template that defines how the arguments are formatted</param>
/// <param name="args">A list of arguments to be used in formatting</param>
/// <param name="cache">Outputs an object that increases performance if the same format string is used repeatedly.</param>
public static string FormatSmart(this string format, ref FormatCache? cache, params object[] args)
{
// With cache:
return Smart.Default.FormatWithCache(ref cache, format, args);
}

#endregion
}
}
89 changes: 54 additions & 35 deletions src/SmartFormat/SmartFormatter.cs
Original file line number Diff line number Diff line change
@@ -252,7 +252,7 @@ public string Format(IFormatProvider? provider, string format, IList<object> arg
var output = new StringOutput(format.Length + args.Count * 8);
var formatParsed = Parser.ParseFormat(format);
var current = args.Count > 0 ? args[0] : args; // The first item is the default.
var formatDetails = new FormatDetails(this, formatParsed, args, null, provider, output);
var formatDetails = new FormatDetails(this, formatParsed, args, provider, output);
Format(formatDetails, current);

return output.ToString();
@@ -279,76 +279,95 @@ public void FormatInto(IOutput output, string format, IList<object> args)
{
var formatParsed = Parser.ParseFormat(format);
var current = args.Count > 0 ? args[0] : args; // The first item is the default.
var formatDetails = new FormatDetails(this, formatParsed, args, null, null, output);
var formatDetails = new FormatDetails(this, formatParsed, args, null, output);
Format(formatDetails, current);
}

private void Format(FormatDetails formatDetails, object current)
{
var formattingInfo = new FormattingInfo(formatDetails, formatDetails.OriginalFormat, current);
Format(formattingInfo);
}

#endregion

#region: Format Overloads with cached Format :

/// <summary>
/// Replaces one or more format items in a specified string with the string representation of a specific object,
/// using the <see cref="FormatCache"/>.
/// Replaces one or more format items in as specified string with the string representation of a specific object.
/// </summary>
/// <param name="cache">The <see cref="FormatCache" /> to use.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">The objects to format.</param>
/// <param name="format">An instance of <see cref="Core.Parsing.Format"/> that was returned by <see cref="SmartFormat.Core.Parsing.Parser.ParseFormat"/>.</param>
/// <param name="args">The object to format.</param>
/// <returns>Returns the formatted input with items replaced with their string representation.</returns>
public string FormatWithCache(ref FormatCache? cache, string format, params object[] args)
public string Format(Format format, params object[] args)
{
return FormatWithCache(ref cache, format, (IList<object>) args);
return Format(null, format, (IList<object>) args);
}

/// <summary>
/// Replaces one or more format items in a specified string with the string representation of a specific object,
/// using the <see cref="FormatCache"/>.
/// Replaces one or more format items in as specified string with the string representation of a specific object.
/// </summary>
/// <param name="cache">The <see cref="FormatCache" /> to use.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">The objects to format.</param>
/// <param name="format">An instance of <see cref="Core.Parsing.Format"/> that was returned by <see cref="SmartFormat.Core.Parsing.Parser.ParseFormat"/>.</param>
/// <param name="args">The object to format.</param>
/// <returns>Returns the formatted input with items replaced with their string representation.</returns>
public string FormatWithCache(ref FormatCache? cache, string format, IList<object> args)
public string Format(Format format, IList<object> args)
{
var output = new StringOutput(format.Length + args.Count * 8);
return Format(null, format, args);
}

/// <summary>
/// Replaces one or more format items in a specified string with the string representation of a specific object.
/// </summary>
/// <param name="provider">The <see cref="IFormatProvider" /> to use.</param>
/// <param name="format">An instance of <see cref="Core.Parsing.Format"/> that was returned by <see cref="SmartFormat.Core.Parsing.Parser.ParseFormat"/>.</param>
/// <param name="args">The object to format.</param>
/// <returns>Returns the formatted input with items replaced with their string representation.</returns>
public string Format(IFormatProvider? provider, Format format, params object[] args)
{
return Format(provider, format, (IList<object>) args);
}

cache ??= new FormatCache(Parser.ParseFormat(format));
/// <summary>
/// Replaces one or more format items in a specified string with the string representation of a specific object.
/// </summary>
/// <param name="provider">The <see cref="IFormatProvider" /> to use.</param>
/// <param name="format">An instance of <see cref="Core.Parsing.Format"/> that was returned by <see cref="SmartFormat.Core.Parsing.Parser.ParseFormat"/>.</param>
/// <param name="args">The object to format.</param>
/// <returns>Returns the formatted input with items replaced with their string representation.</returns>
public string Format(IFormatProvider? provider, Format format, IList<object> args)
{
var output = new StringOutput(format.Length + args.Count * 8);
var current = args.Count > 0 ? args[0] : args; // The first item is the default.
var formatDetails = new FormatDetails(this, cache.Format, args, cache, null, output);
var formatDetails = new FormatDetails(this, format, args, provider, output);
Format(formatDetails, current);

return output.ToString();
}

/// <summary>
/// Writes the formatting result into an <see cref="IOutput"/> instance, using the <see cref="FormatCache"/>.
/// Writes the formatting result into an <see cref="IOutput"/> instance.
/// </summary>
/// <param name="cache">The <see cref="FormatCache"/> to use.</param>
/// <param name="output">The <see cref="IOutput"/> where the result is written to.</param>
/// <param name="format">The format string.</param>
/// <param name="format">An instance of <see cref="Core.Parsing.Format"/> that was returned by <see cref="SmartFormat.Core.Parsing.Parser.ParseFormat"/>.</param>
/// <param name="args">The objects to format.</param>
public void FormatWithCacheInto(ref FormatCache cache, IOutput output, string format, params object[] args)
public void FormatInto(IOutput output, Format format, params object[] args)
{
FormatWithCacheInto(ref cache, output, format, (IList<object>) args);
FormatInto(output, format, (IList<object>) args);
}

/// <summary>
/// Writes the formatting result into an <see cref="IOutput"/> instance, using the <see cref="FormatCache"/>.
/// Writes the formatting result into an <see cref="IOutput"/> instance.
/// </summary>
/// <param name="cache">The <see cref="FormatCache"/> to use.</param>
/// <param name="output">The <see cref="IOutput"/> where the result is written to.</param>
/// <param name="format">The format string.</param>
/// <param name="format">An instance of <see cref="Core.Parsing.Format"/> that was returned by <see cref="SmartFormat.Core.Parsing.Parser.ParseFormat"/>.</param>
/// <param name="args">The objects to format.</param>
public void FormatWithCacheInto(ref FormatCache cache, IOutput output, string format, IList<object> args)
public void FormatInto(IOutput output, Format format, IList<object> args)
{
cache ??= new FormatCache(Parser.ParseFormat(format));
var current = args.Count > 0 ? args[0] : args; // The first item is the default.
var formatDetails = new FormatDetails(this, cache.Format, args, cache, null, output);
var formatDetails = new FormatDetails(this, format, args, null, output);
Format(formatDetails, current);
}

private void Format(FormatDetails formatDetails, object current)
{
var formattingInfo = new FormattingInfo(formatDetails, formatDetails.OriginalFormat, current);
Format(formattingInfo);
}

#endregion

#region: Format :

0 comments on commit 7c84733

Please sign in to comment.