Skip to content

Commit

Permalink
Refactor ListFormatter
Browse files Browse the repository at this point in the history
  • Loading branch information
axunonb committed Aug 6, 2022
1 parent 0f8dbd1 commit a7089c1
Showing 1 changed file with 25 additions and 20 deletions.
45 changes: 25 additions & 20 deletions src/SmartFormat/Extensions/ListFormatter.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//
//
// Copyright SmartFormat Project maintainers and contributors.
// Licensed under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using SmartFormat.Core.Extensions;
using SmartFormat.Core.Parsing;
Expand Down Expand Up @@ -188,16 +187,14 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
// itemFormat|spacer|lastSpacer
// itemFormat|spacer|lastSpacer|twoSpacer
var itemFormat = parameters[0];
var spacer = parameters[1];
var lastSpacer = parameters.Count >= 3 ? parameters[2] : spacer;
var twoSpacer = parameters.Count >= 4 ? parameters[3] : lastSpacer;

if (!itemFormat.HasNested)
{
// The format is not nested,
// so we will treat it as an ItemFormat:
var newItemFormat = FormatPool.Instance.Get().Initialize(_smartSettings, itemFormat.BaseString,
itemFormat.StartIndex, itemFormat.EndIndex, true);
itemFormat.ParentPlaceholder = formattingInfo.Placeholder;

var newPlaceholder = PlaceholderPool.Instance.Get().Initialize(newItemFormat, itemFormat.StartIndex, 0);
newPlaceholder.Format = itemFormat;
Expand All @@ -210,7 +207,7 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
}

// Let's buffer all items from the enumerable (to ensure the Count without double-enumeration):
List<object>? itemsAsList = null;
using var objectListPooledObject = ListPool<object>.Instance.Get(out var itemsAsList);
if (currentAsEnumerable is not ICollection items)
{
itemsAsList = ListPool<object>.Instance.Get();
Expand All @@ -224,11 +221,30 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
var savedCollectionIndex = CollectionIndex;
CollectionIndex = -1;

FormatItems(items, parameters, itemFormat, formattingInfo);

CollectionIndex = savedCollectionIndex; // Restore the CollectionIndex

parameters.Clear();

return true;
}

private static void FormatItems(ICollection items, SplitList parameters, Format itemFormat,
IFormattingInfo formattingInfo)
{
var format = formattingInfo.Format!; // can't be null

// Do not inherit alignment for the spacers - use new FormattingInfo
var spacerFormattingInfo = FormattingInfoPool.Instance.Get()
.Initialize(null, formattingInfo.FormatDetails, format, null);
using var fmtInfoPooledObject = FormattingInfoPool.Instance.Get(out var spacerFormattingInfo);
spacerFormattingInfo.Initialize((Core.Formatting.FormattingInfo)formattingInfo, formattingInfo.FormatDetails,
format, null);
spacerFormattingInfo.Alignment = 0;

var spacer = parameters[1];
var lastSpacer = parameters.Count >= 3 ? parameters[2] : spacer;
var twoSpacer = parameters.Count >= 4 ? parameters[3] : lastSpacer;

// Note:
// Give spacers the data context of the root parent.
// formattingInfo.CurrentValue from the argument to
Expand All @@ -244,7 +260,7 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
foreach (var item in items)
{
CollectionIndex += 1; // Keep track of the index

// Determine which spacer to write:
if (spacer == null || CollectionIndex == 0)
{
Expand All @@ -266,17 +282,6 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
// Output the nested format for this item:
formattingInfo.FormatAsChild(itemFormat, item);
}

CollectionIndex = savedCollectionIndex; // Restore the CollectionIndex

FormattingInfoPool.Instance.Return(spacerFormattingInfo);

if (itemsAsList != null)
ListPool<object>.Instance.Return(itemsAsList);

parameters.Clear();

return true;
}

private static void WriteSpacer(IFormattingInfo formattingInfo, Format spacer, object? value)
Expand Down

0 comments on commit a7089c1

Please sign in to comment.