Skip to content

Commit

Permalink
Support primitive type interpolation
Browse files Browse the repository at this point in the history
  • Loading branch information
boma96 committed Sep 28, 2023
1 parent bc44d1c commit bf4e5dd
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 12 deletions.
37 changes: 28 additions & 9 deletions src/ConductorSharp.Engine/Util/ExpressionUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,7 @@ expression is MethodCallExpression methodExpression
&& methodExpression.Method.DeclaringType == typeof(string)
)
{
var expressionStrings = methodExpression.Arguments.Skip(1).Select(CompileInterpolatedStringArgument).ToArray();
var formatExpr = methodExpression.Arguments[0] as ConstantExpression;
if (formatExpr == null)
throw new Exception("string.Format with non constant format string is not supported");
var formatString = (string)formatExpr.Value;
return string.Format(formatString, expressionStrings);
return CompileStringInterpolationExpression(methodExpression);
}

if (expression is NewExpression || expression is MemberInitExpression)
Expand All @@ -70,6 +65,27 @@ expression is MethodCallExpression methodExpression
return CompileInterpolatedStringArgument(expression);
}

private static object CompileStringInterpolationExpression(MethodCallExpression methodExpression)
{
var interpolationArguments = GetInterpolationArguments(methodExpression);
var expressionStrings = interpolationArguments.Select(CompileInterpolatedStringArgument).ToArray();
var formatExpr = methodExpression.Arguments[0] as ConstantExpression;
if (formatExpr == null)
throw new Exception("string.Format with non constant format string is not supported");
var formatString = (string)formatExpr.Value;
return string.Format(formatString, expressionStrings);
}

private static IEnumerable<Expression> GetInterpolationArguments(MethodCallExpression methodExpression)
{
var methodParams = methodExpression.Method.GetParameters();

//If it is Format(String, Object[]) overload then extract arguments from array, otherwise we assume it is 1, 2, or 3 formatting argument method
return methodParams.Length == 2 && methodParams[0].ParameterType == typeof(string) && methodParams[1].ParameterType.IsArray
? ((NewArrayExpression)methodExpression.Arguments[1]).Expressions
: methodExpression.Arguments.Skip(1); // Skip format string
}

private static object ParseBinaryExpression(BinaryExpression binaryEx)
{
var left = ParseExpression(binaryEx.Left);
Expand Down Expand Up @@ -187,7 +203,7 @@ var member in newExpression.Arguments.Zip(
return inputParams;
}

private static string CompileInterpolatedStringArgument(Expression expr)
private static object CompileInterpolatedStringArgument(Expression expr)
{
if (expr is MemberExpression || IsDictionaryIndexExpression(expr))
return CreateExpressionString(expr);
Expand All @@ -198,8 +214,11 @@ expr is MethodCallExpression methodExpr
)
return (string)methodExpr.Method.Invoke(null, null);
if (expr is ConstantExpression cex)
return (string)ParseConstantExpression(cex);
throw new Exception($"Expression {expr.GetType().Name} not supported");
return ParseConstantExpression(cex);
if (expr is UnaryExpression uex && uex.NodeType == ExpressionType.Convert)
return CompileInterpolatedStringArgument(uex.Operand);

throw new Exception($"Expression {expr.GetType().Name} in interpolated string not supported");
}

private static string CreateExpressionString(Expression expression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class StringInterpolationOutput : WorkflowOutput
[OriginalName("TEST_StringInterpolation")]
public class StringInterpolation : Workflow<StringInterpolation, StringInterpolationInput, StringInterpolationOutput>
{
public const string Constant = "Value";
public const string ConstantStr = "Value";
public const int ConstantPrimitive = 0;

public StringInterpolation(WorkflowDefinitionBuilder<StringInterpolation, StringInterpolationInput, StringInterpolationOutput> builder)
: base(builder) { }
Expand All @@ -35,7 +36,7 @@ public override void BuildDefinition()
wf =>
new()
{
Address = $"{wf.WorkflowInput.FirstInput},{wf.WorkflowInput.SecondInput},{Constant}",
Address = $"{wf.WorkflowInput.FirstInput},{wf.WorkflowInput.SecondInput},{ConstantStr},{ConstantPrimitive}",
Name = $"Workflow name: {NamingUtil.NameOf<StringInterpolation>()}"
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"taskReferenceName": "email_prepare",
"description": "{\"description\":null}",
"inputParameters": {
"address": "${workflow.input.first_input},${workflow.input.second_input},Value",
"address": "${workflow.input.first_input},${workflow.input.second_input},Value,0",
"name": "Workflow name: TEST_StringInterpolation"
},
"type": "SIMPLE",
Expand Down

0 comments on commit bf4e5dd

Please sign in to comment.