From f753f1a30cf57c78a88e36182440b9b4c0d5763a Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Fri, 23 Dec 2016 12:43:45 +0100 Subject: [PATCH] Better integration of Option with string formatting Closes #20 --- Optional.Tests/MaybeTests.cs | 34 +++++++++++++++++++++++++++++++++- Optional/Option_Maybe.cs | 11 +++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Optional.Tests/MaybeTests.cs b/Optional.Tests/MaybeTests.cs index 29d12e3..548606c 100644 --- a/Optional.Tests/MaybeTests.cs +++ b/Optional.Tests/MaybeTests.cs @@ -1,6 +1,7 @@ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.IO; using System.Runtime.Serialization.Formatters.Binary; @@ -166,7 +167,38 @@ public void Maybe_StringRepresentation() } [TestMethod] - public void Maybe_GetValue() + public void Maybe_Format() + { + Assert.AreEqual("", ((IFormattable) Option.None()).ToString(null, null)); + Assert.AreEqual("", ((IFormattable) Option.None()).ToString(null, null)); + Assert.AreEqual("", ((IFormattable) Option.None()).ToString(null, null)); + + Assert.AreEqual("", ((IFormattable) Option.Some(null)).ToString(null, null)); + Assert.AreEqual("", ((IFormattable) Option.Some(null)).ToString(null, null)); + + // Test number formatting using a culture that uses a different + // separator for grouping than the current culture. + + var numberFormatProvider = + CultureInfo.GetCultures(CultureTypes.SpecificCultures) + .First(ci => ci.NumberFormat.NumberGroupSeparator != NumberFormatInfo.CurrentInfo.NumberGroupSeparator); + + Assert.AreEqual(int.MaxValue.ToString("N0", numberFormatProvider), ((IFormattable) Option.Some(int.MaxValue)).ToString("N0", numberFormatProvider)); + Assert.AreEqual(int.MaxValue.ToString("N0", numberFormatProvider), ((IFormattable) Option.Some(int.MaxValue)).ToString("N0", numberFormatProvider)); + + // Test date formatting using a culture that would yield a + // different result than the current culture. + + var now = DateTime.Now; + var dateFormatProvider = + CultureInfo.GetCultures(CultureTypes.SpecificCultures) + .First(ci => now.ToString("D", ci) != now.ToLongDateString()); + + Assert.AreEqual(now.ToString("D", dateFormatProvider), ((IFormattable) Option.Some(now)).ToString("D", dateFormatProvider)); + } + + [TestMethod] + public void Maybe_GetValue() { var noneStruct = Option.None(); var noneNullable = Option.None(); diff --git a/Optional/Option_Maybe.cs b/Optional/Option_Maybe.cs index f1d7417..7a65ce9 100644 --- a/Optional/Option_Maybe.cs +++ b/Optional/Option_Maybe.cs @@ -14,7 +14,7 @@ namespace Optional [Serializable] #endif [DebuggerDisplay("{" + nameof(DebugString) + "}")] - public struct Option : IEquatable> + public struct Option : IEquatable>, IFormattable { private readonly bool hasValue; private readonly T value; @@ -391,5 +391,12 @@ public Option Filter(Func predicate) /// /// The filtered optional. public Option NotNull() => hasValue && value == null ? Option.None() : this; - } + + string IFormattable.ToString(string format, IFormatProvider formatProvider) + { + return hasValue + ? string.Format(formatProvider, "{0:" + format + "}", value) + : string.Empty; + } +} }