Skip to content

Commit

Permalink
Refactored TimeTextInfo (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
axunonb committed Dec 23, 2021
1 parent 2ec6cf0 commit ff72f7c
Show file tree
Hide file tree
Showing 7 changed files with 374 additions and 334 deletions.
34 changes: 18 additions & 16 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ SmartFormat is not a fully-fledged HTML parser. If this is required, use [AngleS
b) Get the culture from the `IFormatProvider` argument (which may be a `CultureInfo`) to `SmartFormatter.Format(IFormatProvider, string, object?[])`<br/>
c) The `CultureInfo.CurrentUICulture`<br/>

### 20. Refactored `TimeFormatter` ([#220](https://github.com/axuno/SmartFormat/pull/220), [#221](https://github.com/axuno/SmartFormat/pull/221))
### 20. Refactored `TimeFormatter` ([#220](https://github.com/axuno/SmartFormat/pull/220), [#221](https://github.com/axuno/SmartFormat/pull/221), [#234](https://github.com/axuno/SmartFormat/pull/234))
* Constructor with string argument for default language is obsolete.
* Property `DefaultTwoLetterISOLanguageName` is obsolete.
Expand All @@ -323,21 +323,23 @@ SmartFormat is not a fully-fledged HTML parser. If this is required, use [AngleS
* **New:** Custom languages can now easily be added to `CommonLanguagesTimeTextInfo`. Custom languages override built-in definitions.
```CSharp
var language = "nl"; // dummy - it's English, not Dutch ;-)
TimeTextInfo custom = new(
pluralRule: PluralRules.GetPluralRule(language),
week: new[] { "{0} week", "{0} weeks" },
day: new[] { "{0} day", "{0} days" },
hour: new[] { "{0} hour", "{0} hours" },
minute: new[] { "{0} minute", "{0} minutes" },
second: new[] { "{0} second", "{0} seconds" },
millisecond: new[] { "{0} millisecond", "{0} milliseconds" },
w: new[] { "{0}w" },
d: new[] { "{0}d" },
h: new[] { "{0}h" },
m: new[] { "{0}m" },
s: new[] { "{0}s" },
ms: new[] { "{0}ms" },
lessThan: "less than {0}");
TimeTextInfo custom = new()
{
PluralRule = PluralRules.GetPluralRule(language),
Ptxt_week = new[] { "{0} week", "{0} weeks" },
Ptxt_day = new[] { "{0} day", "{0} days" },
Ptxt_hour = new[] { "{0} hour", "{0} hours" },
Ptxt_minute = new[] { "{0} minute", "{0} minutes" },
Ptxt_second = new[] { "{0} second", "{0} seconds" },
Ptxt_millisecond = new[] { "{0} millisecond", "{0} milliseconds" },
Ptxt_w = new[] { "{0}w" },
Ptxt_d = new[] { "{0}d" },
Ptxt_h = new[] { "{0}h" },
Ptxt_m = new[] { "{0}m" },
Ptxt_s = new[] { "{0}s" },
Ptxt_ms = new[] { "{0}ms" },
Ptxt_lessThan = "less than {0}"
};
CommonLanguagesTimeTextInfo.AddLanguage(language, custom)
```
* **Changed:**
Expand Down
64 changes: 34 additions & 30 deletions src/SmartFormat.Tests/Utilities/CommonLanguagesTimeTextInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,23 @@ public void Get_TimeTextInfo_For_BuiltIn_Languages(string language, string prope
public void Add_Valid_Custom_Language_TimeTextInfo()
{
var language = "nl"; // dummy - it's English, not Dutch ;-)
TimeTextInfo custom = new(
pluralRule: PluralRules.GetPluralRule(language),
week: new[] { "{0} week", "{0} weeks" },
day: new[] { "{0} day", "{0} days" },
hour: new[] { "{0} hour", "{0} hours" },
minute: new[] { "{0} minute", "{0} minutes" },
second: new[] { "{0} second", "{0} seconds" },
millisecond: new[] { "{0} millisecond", "{0} milliseconds" },
w: new[] { "{0}w" },
d: new[] { "{0}d" },
h: new[] { "{0}h" },
m: new[] { "{0}m" },
s: new[] { "{0}s" },
ms: new[] { "{0}ms" },
lessThan: "less than {0}");
TimeTextInfo custom = new()
{
PluralRule = PluralRules.GetPluralRule(language),
Ptxt_week = new[] { "{0} week", "{0} weeks" },
Ptxt_day = new[] { "{0} day", "{0} days" },
Ptxt_hour = new[] { "{0} hour", "{0} hours" },
Ptxt_minute = new[] { "{0} minute", "{0} minutes" },
Ptxt_second = new[] { "{0} second", "{0} seconds" },
Ptxt_millisecond = new[] { "{0} millisecond", "{0} milliseconds" },
Ptxt_w = new[] { "{0}w" },
Ptxt_d = new[] { "{0}d" },
Ptxt_h = new[] { "{0}h" },
Ptxt_m = new[] { "{0}m" },
Ptxt_s = new[] { "{0}s" },
Ptxt_ms = new[] { "{0}ms" },
Ptxt_lessThan = "less than {0}"
};

Assert.That(() => CommonLanguagesTimeTextInfo.AddLanguage(language, custom), Throws.Nothing);
Assert.That(() => CommonLanguagesTimeTextInfo.GetTimeTextInfo(language), Is.EqualTo(custom));
Expand All @@ -54,21 +56,23 @@ public void Add_Invalid_Custom_Language_TimeTextInfo_Should_Throw()
var language = "123xyz";
Assert.That(() =>
{
TimeTextInfo custom = new(
pluralRule: PluralRules.GetPluralRule(language),
week: new[] { "{0} week", "{0} weeks" },
day: new[] { "{0} day", "{0} days" },
hour: new[] { "{0} hour", "{0} hours" },
minute: new[] { "{0} minute", "{0} minutes" },
second: new[] { "{0} second", "{0} seconds" },
millisecond: new[] { "{0} millisecond", "{0} milliseconds" },
w: new[] { "{0}w" },
d: new[] { "{0}d" },
h: new[] { "{0}h" },
m: new[] { "{0}m" },
s: new[] { "{0}s" },
ms: new[] { "{0}ms" },
lessThan: "less than {0}");
TimeTextInfo custom = new()
{
PluralRule = PluralRules.GetPluralRule(language),
Ptxt_week = new[] { "{0} week", "{0} weeks" },
Ptxt_day = new[] { "{0} day", "{0} days" },
Ptxt_hour = new[] { "{0} hour", "{0} hours" },
Ptxt_minute = new[] { "{0} minute", "{0} minutes" },
Ptxt_second = new[] { "{0} second", "{0} seconds" },
Ptxt_millisecond = new[] { "{0} millisecond", "{0} milliseconds" },
Ptxt_w = new[] { "{0}w" },
Ptxt_d = new[] { "{0}d" },
Ptxt_h = new[] { "{0}h" },
Ptxt_m = new[] { "{0}m" },
Ptxt_s = new[] { "{0}s" },
Ptxt_ms = new[] { "{0}ms" },
Ptxt_lessThan = "less than {0}"
};
CommonLanguagesTimeTextInfo.AddLanguage(language, custom);
},
Expand Down
43 changes: 25 additions & 18 deletions src/SmartFormat/Extensions/TimeFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,31 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
var v2Compatibility = options != string.Empty && formatText == string.Empty;
var formattingOptions = v2Compatibility ? options : formatText;

TimeSpan? fromTime = null;
var fromTime = GetFromTime(current, formattingOptions);

if (fromTime is null)
{
// Auto detection calls just return a failure to evaluate
if (formatterName == string.Empty)
return false;

// throw, if the formatter has been called explicitly
throw new FormatException(
$"Formatter named '{formatterName}' can only process types of {nameof(TimeSpan)}, {nameof(DateTime)}, {nameof(DateTimeOffset)}");
}

var timeTextInfo = GetTimeTextInfo(formattingInfo, v2Compatibility);

var timeSpanFormatOptions = TimeSpanFormatOptionsConverter.Parse(v2Compatibility ? options : formatText);
var timeString = fromTime.Value.ToTimeString(timeSpanFormatOptions, timeTextInfo);
formattingInfo.Write(timeString);
return true;
}

private static TimeSpan? GetFromTime(object? current, string? formattingOptions)
{
TimeSpan? fromTime = null;

switch (current)
{
case TimeSpan timeSpan:
Expand All @@ -165,23 +188,7 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
break;
}

if (fromTime is null)
{
// Auto detection calls just return a failure to evaluate
if (formatterName == string.Empty)
return false;

// throw, if the formatter has been called explicitly
throw new FormatException(
$"Formatter named '{formatterName}' can only process types of {nameof(TimeSpan)}, {nameof(DateTime)}, {nameof(DateTimeOffset)}");
}

var timeTextInfo = GetTimeTextInfo(formattingInfo, v2Compatibility);

var timeSpanFormatOptions = TimeSpanFormatOptionsConverter.Parse(v2Compatibility ? options : formatText);
var timeString = fromTime.Value.ToTimeString(timeSpanFormatOptions, timeTextInfo);
formattingInfo.Write(timeString);
return true;
return fromTime;
}

private TimeTextInfo GetTimeTextInfo(IFormattingInfo formattingInfo, bool v2Compatibility)
Expand Down
Loading

0 comments on commit ff72f7c

Please sign in to comment.