diff --git a/src/libraries/Microsoft.PowerFx.Core/Public/Values/FormulaValue.cs b/src/libraries/Microsoft.PowerFx.Core/Public/Values/FormulaValue.cs index 3fc4e0d91d..30d9d2e6fd 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Public/Values/FormulaValue.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Public/Values/FormulaValue.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +using System; using System.Diagnostics; using System.Text; using Microsoft.PowerFx.Core.IR; @@ -88,6 +89,68 @@ public bool TryGetPrimitiveValue(out object val) val = null; return false; + } + + public bool AsBoolean() + { + if (this is BlankValue) + { + return default; + } + + if (TryGetPrimitiveValue(out object val)) + { + if (val is bool b) + { + return b; + } + } + + throw new InvalidOperationException($"Can't coerce to double from {this.Type._type.GetKindString()})"); + } + + public double AsDouble() + { + if (this is BlankValue) + { + return default; + } + + if (TryGetPrimitiveValue(out object val)) + { + if (val is double d1) + { + return d1; + } + else if (val is decimal d2) + { + return (double)d2; + } + } + + throw new InvalidOperationException($"Can't coerce to double from {this.Type._type.GetKindString()})"); + } + + public decimal AsDecimal() + { + if (this is BlankValue) + { + return default; + } + + if (TryGetPrimitiveValue(out object val)) + { + if (val is double d1) + { + return (decimal)d1; + } + else if (val is decimal d2) + { + return d2; + } + } + + throw new InvalidOperationException($"Can't coerce to decimal from {this.Type._type.GetKindString()})"); } } } diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/ValueTests.cs b/src/tests/Microsoft.PowerFx.Interpreter.Tests/ValueTests.cs index 2ed8538456..19a54ff478 100644 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/ValueTests.cs +++ b/src/tests/Microsoft.PowerFx.Interpreter.Tests/ValueTests.cs @@ -423,6 +423,52 @@ public void TryGetIntTest(double doubleValue, decimal decimalValue, string strin Assert.False(Library.TryGetInt(str, out int outputStringToInt)); } + + [Fact] + public void AsNumberTests() + { + NumberValue num = FormulaValue.New((double)1.2); + DecimalValue dec = FormulaValue.New(1.2m); + + Assert.Equal(1.2, num.AsDouble()); + Assert.Equal(1.2, dec.AsDouble()); + + Assert.Equal(1.2m, num.AsDecimal()); + Assert.Equal(1.2m, dec.AsDecimal()); + } + + [Fact] + public void AsNumberTestsBlank() + { + BlankValue num = FormulaValue.NewBlank(FormulaType.Number); + BlankValue dec = FormulaValue.NewBlank(FormulaType.Decimal); + + Assert.Equal(0, num.AsDouble()); + Assert.Equal(0m, dec.AsDecimal()); + } + + [Fact] + public void AsBooleanTests() + { + var x = FormulaValue.New(true); + + bool b = x.AsBoolean(); + Assert.True(x.AsBoolean()); + + var x2 = FormulaValue.NewBlank(FormulaType.Boolean); + bool b2 = x2.AsBoolean(); + Assert.False(x2.AsBoolean()); + } + + [Fact] + public void AsNumberFailTests() + { + StringValue num = FormulaValue.New("1.2"); + + Assert.Throws(() => num.AsDouble()); + Assert.Throws(() => num.AsDecimal()); + Assert.Throws(() => num.AsBoolean()); + } } public static class FormulaValueExtensions