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 format provider argument to IParseable.Parse() #6065

Merged
merged 21 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions osu.Framework.Tests/Bindables/BindableDoubleTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Globalization;
using NUnit.Framework;
using osu.Framework.Bindables;

Expand Down Expand Up @@ -98,5 +99,18 @@ public void TestPropagationToPlainBindable()
number.MinValue = 0;
number.MaxValue = 10;
}

[TestCase("1,4", "de-DE", 1.4)]
[TestCase("1.400,01", "de-DE", 1400.01)]
[TestCase("1 234,57", "ru-RU", 1234.57)]
[TestCase("1,094", "fr-FR", 1.094)]
[TestCase("1,400.01", "zh-CN", 1400.01)]
public void TestParsingLocale(string value, string locale, double expected)
{
var bindable = new BindableDouble();
bindable.Parse(value, CultureInfo.GetCultureInfo(locale));

Assert.AreEqual(expected, bindable.Value);
}
}
}
14 changes: 14 additions & 0 deletions osu.Framework.Tests/Bindables/BindableFloatTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Globalization;
using NUnit.Framework;
using osu.Framework.Bindables;

Expand Down Expand Up @@ -85,5 +86,18 @@ public void TestParsingFloat(float value)

Assert.AreEqual(value, bindable.Value);
}

[TestCase("1,4", "de-DE", 1.4f)]
[TestCase("1.400,01", "de-DE", 1400.01f)]
[TestCase("1 234,57", "ru-RU", 1234.57f)]
[TestCase("1,094", "fr-FR", 1.094f)]
[TestCase("1,400.01", "zh-CN", 1400.01f)]
public void TestParsingLocale(string value, string locale, float expected)
Neuheit marked this conversation as resolved.
Show resolved Hide resolved
{
var bindable = new BindableFloat();
bindable.Parse(value, CultureInfo.GetCultureInfo(locale));

Assert.AreEqual(expected, bindable.Value);
}
}
}
7 changes: 4 additions & 3 deletions osu.Framework/Bindables/Bindable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace osu.Framework.Bindables
/// A generic implementation of a <see cref="IBindable"/>
/// </summary>
/// <typeparam name="T">The type of our stored <see cref="Value"/>.</typeparam>
public class Bindable<T> : IBindable<T>, IBindable, IParseable, ISerializableBindable
public class Bindable<T> : IBindable<T>, IBindable, ILocalisableParseable, ISerializableBindable
{
/// <summary>
/// An event which is raised when <see cref="Value"/> has changed (or manually via <see cref="TriggerValueChange"/>).
Expand Down Expand Up @@ -248,7 +248,8 @@ private void addWeakReference(WeakReference<Bindable<T>> weakReference)
/// An object deriving T can be parsed, or a string can be parsed if T is an enum type.
/// </summary>
/// <param name="input">The input which is to be parsed.</param>
public virtual void Parse([CanBeNull] object input)
/// <param name="cultureInfo">The preferred culture formatting to be displayed.</param>
public virtual void Parse([CanBeNull] object input, [CanBeNull] CultureInfo cultureInfo = null)
Neuheit marked this conversation as resolved.
Show resolved Hide resolved
{
switch (input)
{
Expand Down Expand Up @@ -295,7 +296,7 @@ public virtual void Parse([CanBeNull] object input)
if (underlyingType.IsEnum)
Value = (T)Enum.Parse(underlyingType, input.ToString().AsNonNull());
else
Value = (T)Convert.ChangeType(input, underlyingType, CultureInfo.InvariantCulture);
Value = (T)Convert.ChangeType(input, underlyingType, cultureInfo ?? CultureInfo.InvariantCulture);
Neuheit marked this conversation as resolved.
Show resolved Hide resolved

break;
}
Expand Down
5 changes: 3 additions & 2 deletions osu.Framework/Bindables/BindableBool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Globalization;

namespace osu.Framework.Bindables
{
Expand All @@ -12,7 +13,7 @@ public BindableBool(bool value = false)
{
}

public override void Parse(object? input)
public override void Parse(object? input, CultureInfo? cultureInfo = null)
{
if (input == null) throw new ArgumentNullException(nameof(input));

Expand All @@ -21,7 +22,7 @@ public override void Parse(object? input)
else if (input is "0")
Value = false;
else
base.Parse(input);
base.Parse(input, cultureInfo);
}

public void Toggle() => Value = !Value;
Expand Down
5 changes: 3 additions & 2 deletions osu.Framework/Bindables/BindableColour4.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Globalization;
using osu.Framework.Graphics;

namespace osu.Framework.Bindables
Expand All @@ -16,7 +17,7 @@ public BindableColour4(Colour4 value = default)
// 8-bit precision should probably be enough for serialization.
public override string ToString(string? format, IFormatProvider? formatProvider) => Value.ToHex();

public override void Parse(object? input)
public override void Parse(object? input, CultureInfo? cultureInfo = null)
{
if (input == null) throw new ArgumentNullException(nameof(input));

Expand All @@ -30,7 +31,7 @@ public override void Parse(object? input)
break;

default:
base.Parse(input);
base.Parse(input, cultureInfo);
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions osu.Framework/Bindables/BindableMarginPadding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public BindableMarginPadding(MarginPadding defaultValue = default)
{
}

public override void Parse(object? input)
public override void Parse(object? input, CultureInfo? cultureInfo = null)
{
if (input == null) throw new ArgumentNullException(nameof(input));

Expand All @@ -39,7 +39,7 @@ public override void Parse(object? input)
break;

default:
base.Parse(input);
base.Parse(input, cultureInfo);
break;
}
}
Expand Down
5 changes: 3 additions & 2 deletions osu.Framework/Bindables/BindableSize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Drawing;
using System.Globalization;

namespace osu.Framework.Bindables
{
Expand All @@ -21,7 +22,7 @@ public BindableSize(Size defaultValue = default)

public override string ToString(string? format, IFormatProvider? formatProvider) => ((FormattableString)$"{Value.Width}x{Value.Height}").ToString(formatProvider);

public override void Parse(object? input)
public override void Parse(object? input, CultureInfo? cultureInfo = null)
{
if (input == null) throw new ArgumentNullException(nameof(input));

Expand All @@ -37,7 +38,7 @@ public override void Parse(object? input)
break;

default:
base.Parse(input);
base.Parse(input, cultureInfo);
break;
}
}
Expand Down
20 changes: 20 additions & 0 deletions osu.Framework/Bindables/ILocalisableParseable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Globalization;

namespace osu.Framework.Bindables
{
/// <summary>
/// Represents a class which can be parsed from an arbitrary object based on locale information.
/// </summary>
public interface ILocalisableParseable
{
/// <summary>
/// Parse an input into this instance.
/// </summary>
/// <param name="input">The input which is to be parsed.</param>
/// <param name="cultureInfo">The preferred culture formatting to be displayed.</param>
void Parse(object input, CultureInfo cultureInfo);
}
}