Skip to content

Commit 4c0eabd

Browse files
Merge pull request #40 from thygesteffensen/fix/valuecontainerconvert
Fix/valuecontainerconvert
2 parents 0cd0c63 + c0e71a3 commit 4c0eabd

34 files changed

+1103
-442
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
GIT_AUTHOR_NAME: thygesteffensen
4747
GIT_AUTHOR_EMAIL: [email protected]
4848
run: |
49-
echo "RELEASE_VERSION=$((npx semantic-release --dry-run).Where({ $_ -like '*Release note*' }) | Out-String | Select-String '[0-9]+\.[0-9]+\.[0-9]+([-][a-zA-z]+[.][0-9]*)' | % { $_.Matches } | % { $_.Value })" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
49+
echo "RELEASE_VERSION=$((npx semantic-release --dry-run).Where({ $_ -like '*Release note*' }) | Out-String | Select-String '[0-9]+\.[0-9]+\.[0-9]+([-][a-zA-z]+[.][0-9]*)?' | % { $_.Matches } | % { $_.Value })" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
5050
5151
- name: Print release verison
5252
run: echo ${env:RELEASE_VERSION}

PowerAutomateMockUp/ExpressionParser/Functions/CustomException/InvalidTemplateException.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,15 @@ public static InvalidTemplateException BuildInvalidTemplateExceptionParameterTyp
5959

6060
return new InvalidTemplateException(msg);
6161
}
62+
63+
public static InvalidTemplateException BuildInvalidLanguageFunction(string actionName, string functionName)
64+
{
65+
var msg = $"InvalidTemplate. Unable to process template language expressions in action '{actionName}' inputs at " +
66+
$"line 'x' and column 'y': 'The template language function '{functionName}' expects a comma separated " +
67+
"list of parameters. The function was invoked with no parameters. " +
68+
"Please see https://aka.ms/logicexpressions#createArray for usage details.'.";
69+
70+
return new InvalidTemplateException(msg);
71+
}
6272
}
6373
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Linq;
2+
using Parser.ExpressionParser.Functions.Base;
3+
using Parser.ExpressionParser.Functions.CustomException;
4+
5+
namespace Parser.ExpressionParser.Functions.Implementations.ConversionFunctions
6+
{
7+
public class CreateArrayFunction : Function
8+
{
9+
public CreateArrayFunction() : base("createArray")
10+
{
11+
}
12+
13+
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
{
15+
if (parameters.Length == 0)
16+
{
17+
throw InvalidTemplateException.BuildInvalidLanguageFunction("SomeActon", "createArray");
18+
}
19+
20+
return new ValueContainer(parameters.ToList());
21+
}
22+
}
23+
}

PowerAutomateMockUp/ExpressionParser/Functions/Implementations/ConversionFunctions/DataUriFunction.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Parser.ExpressionParser.Functions.Base;
2+
using Parser.ExpressionParser.Functions.CustomException;
23

34
namespace Parser.ExpressionParser.Functions.Implementations.ConversionFunctions
45
{
@@ -10,6 +11,11 @@ public DataUriFunction() : base("dataUri")
1011

1112
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
1213
{
14+
if (parameters.Length == 0)
15+
{
16+
throw InvalidTemplateException.BuildInvalidLanguageFunction("SomeActon", "dataUri");
17+
}
18+
1319
return parameters[0].Type() switch
1420
{
1521
ValueContainer.ValueType.String =>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Linq;
3+
using System.Text;
4+
using Parser.ExpressionParser.Functions.Base;
5+
using Parser.ExpressionParser.Functions.CustomException;
6+
7+
namespace Parser.ExpressionParser.Functions.Implementations.ConversionFunctions
8+
{
9+
public class DataUriToBinaryFunction : Function
10+
{
11+
public DataUriToBinaryFunction() : base("dataUriToBinary")
12+
{
13+
}
14+
15+
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
16+
{
17+
if (parameters.Length == 0)
18+
{
19+
throw InvalidTemplateException.BuildInvalidLanguageFunction("SomeActon", "dataUriToBinary");
20+
}
21+
22+
return parameters[0].Type() switch
23+
{
24+
ValueContainer.ValueType.String =>
25+
new ValueContainer(Encoding.UTF8.GetBytes(parameters[0].GetValue<string>())
26+
.Aggregate("", (s, b) => s + Convert.ToString(b, 2).PadLeft(8, '0'))),
27+
_ => throw new PowerAutomateMockUpException(
28+
$"Array function can only operate on strings, not {parameters[0].Type()}.")
29+
};
30+
}
31+
}
32+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Parser.ExpressionParser.Functions.Base;
2+
using Parser.ExpressionParser.Functions.CustomException;
3+
4+
namespace Parser.ExpressionParser.Functions.Math
5+
{
6+
public class AddFunction : Function
7+
{
8+
public AddFunction() : base("add")
9+
{
10+
}
11+
12+
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
13+
{
14+
if (parameters.Length != 2)
15+
{
16+
throw new InvalidTemplateException("Paramters count does not match expected");
17+
}
18+
19+
var first = parameters[0].GetValue<float>();
20+
var second = parameters[1].GetValue<float>();
21+
22+
return new ValueContainer(first + second);
23+
}
24+
}
25+
}

PowerAutomateMockUp/ExpressionParser/Rules/AccessValueRule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public AccessValueRule(IRule func, IEnumerable<IRule> indexRules)
3030

3131
foreach (var accessor in indexes.Skip(1))
3232
{
33-
tempIndexRules.Add(new IndexRule(new ConstantRule(new ValueContainer(accessor)), false));
33+
tempIndexRules.Add(new IndexRule(new ConstantRule(new ValueContainer(accessor)), nullConditional));
3434
}
3535
}
3636
else

PowerAutomateMockUp/ExpressionParser/ValueContainer.cs

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public ValueContainer(string stringValue)
5959

6060
public ValueContainer(float floatValue)
6161
{
62-
_value = floatValue;
62+
_value = Convert.ToDouble(floatValue);
6363
_type = ValueType.Float;
6464
}
6565

@@ -114,8 +114,9 @@ public ValueContainer()
114114

115115
public ValueContainer(JToken json)
116116
{
117-
_type = ValueType.Object;
118-
_value = JsonToValueContainer(json).GetValue<Dictionary<string, ValueContainer>>();
117+
var v = JsonToValueContainer(json);
118+
_type = v._type;
119+
_value = v._value;
119120
}
120121

121122
public ValueType Type()
@@ -223,32 +224,51 @@ public Dictionary<string, ValueContainer> AsDict()
223224

224225
private ValueContainer JsonToValueContainer(JToken json)
225226
{
226-
if (json is JObject jObject)
227+
switch (json)
227228
{
228-
var dictionary = json.ToDictionary(pair => ((JProperty) pair).Name, token =>
229+
case JObject jObject:
229230
{
230-
if (token.Children().Count() != 1) return JsonToValueContainer(token.Children().First());
231+
var dictionary = json.ToDictionary(pair => ((JProperty) pair).Name, token =>
232+
{
233+
if (token.Children().Count() != 1) return JsonToValueContainer(token.Children().First());
234+
235+
var t = token.First;
236+
return t.Type switch
237+
{
238+
JTokenType.String => new ValueContainer(t.Value<string>(), true),
239+
JTokenType.Boolean => new ValueContainer(t.Value<bool>()),
240+
JTokenType.Integer => new ValueContainer(t.Value<int>()),
241+
JTokenType.Float => new ValueContainer(t.Value<float>()),
242+
_ => JsonToValueContainer(token.Children().First())
243+
};
244+
});
245+
246+
return new ValueContainer(dictionary);
247+
}
248+
case JArray jArray:
249+
return jArray.Count > 0 ? new ValueContainer() : JArrayToValueContainer(jArray);
250+
case JValue jValue:
251+
if (jValue.HasValues)
252+
{
253+
throw new PowerAutomateMockUpException(
254+
"When parsing JToken to ValueContainer, the JToken as JValue can only contain one value.");
255+
}
231256

232-
var t = token.First;
233-
return t.Type switch
257+
return jValue.Type switch
234258
{
235-
JTokenType.String => new ValueContainer(t.Value<string>(), true),
236-
JTokenType.Boolean => new ValueContainer(t.Value<bool>()),
237-
JTokenType.Integer => new ValueContainer(t.Value<int>()),
238-
JTokenType.Float => new ValueContainer(t.Value<float>()),
239-
_ => JsonToValueContainer(token.Children().First())
259+
JTokenType.Boolean => new ValueContainer(jValue.Value<bool>()),
260+
JTokenType.Integer => new ValueContainer(jValue.Value<int>()),
261+
JTokenType.Float => new ValueContainer(jValue.Value<float>()),
262+
JTokenType.Null => new ValueContainer(),
263+
JTokenType.String => new ValueContainer(jValue.Value<string>()),
264+
JTokenType.None => new ValueContainer(),
265+
JTokenType.Guid => new ValueContainer(jValue.Value<Guid>().ToString()),
266+
_ => throw new PowerAutomateMockUpException(
267+
$"{jValue.Type} is not yet supported in ValueContainer conversion")
240268
};
241-
});
242-
243-
return new ValueContainer(dictionary);
244-
}
245-
246-
if (json is JArray jArray)
247-
{
248-
return jArray.Count > 0 ? new ValueContainer() : JArrayToValueContainer(jArray);
269+
default:
270+
throw new PowerAutomateMockUpException("Could not parse JToken to ValueContainer.");
249271
}
250-
251-
throw new Exception();
252272
}
253273

254274
private ValueContainer JArrayToValueContainer(JArray json)
@@ -373,6 +393,19 @@ public bool Equals(ValueContainer other)
373393

374394
return thisDict.Count == otherDict.Count && !thisDict.Except(otherDict).Any();
375395
}
396+
case ValueType.Integer when other._type == ValueType.Float:
397+
var v = (double) _value;
398+
return Math.Abs(Math.Floor(v) - other._value) < double.Epsilon;
399+
case ValueType.Float when other._type == ValueType.Integer:
400+
{
401+
return Math.Abs(Math.Floor(_value) - other._value) < double.Epsilon;
402+
}
403+
case ValueType.Float:
404+
{
405+
// TODO: Figure out how to handle comparison and in general how to handle float/double..
406+
// assignee: thygesteffensen
407+
return Math.Abs(_value - other._value) < 0.01;
408+
}
376409
default:
377410
return Equals(_value, other._value) && _type == other._type;
378411
}

PowerAutomateMockUp/FlowParser/ActionExecutors/Implementations/DoUntilActionExecutor.cs renamed to PowerAutomateMockUp/FlowParser/ActionExecutors/Implementations/ControlActions/DoUntilActionExecutor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using Newtonsoft.Json.Linq;
66
using Parser.ExpressionParser;
77

8-
namespace Parser.FlowParser.ActionExecutors.Implementations
8+
namespace Parser.FlowParser.ActionExecutors.Implementations.ControlActions
99
{
1010
public class DoUntilActionExecutor : DefaultBaseActionExecutor, IScopeActionExecutor
1111
{

PowerAutomateMockUp/FlowParser/ActionExecutors/Implementations/ForEachActionExecutor.cs renamed to PowerAutomateMockUp/FlowParser/ActionExecutors/Implementations/ControlActions/ForEachActionExecutor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using Newtonsoft.Json.Linq;
77
using Parser.ExpressionParser;
88

9-
namespace Parser.FlowParser.ActionExecutors.Implementations
9+
namespace Parser.FlowParser.ActionExecutors.Implementations.ControlActions
1010
{
1111
public class ForEachActionExecutor : DefaultBaseActionExecutor, IScopeActionExecutor, IItemHandler
1212
{

0 commit comments

Comments
 (0)