public override async IAsyncEnumerable <Path> ComputeSelect(EvaluationContext ctx) { _listCandidate ??= TemplexBase.Parse(ListExpression); if (_listCandidate != null) { // Expression select var select = _listCandidate.ComputeSelect(ctx); await foreach (var atom in select) { yield return(atom); } // Expression paths var paths = _listCandidate.ComputePaths(ctx); await foreach (var path in paths) { yield return(path.Append("Id")); } // Inner template select var scopedCtx = ctx.Clone(); scopedCtx.SetLocalVariable(IteratorVariableName, new EvaluationVariable( eval: TemplateUtil.VariableThatThrows(IteratorVariableName), selectResolver: () => select, pathsResolver: () => paths )); await foreach (var atom in Inner.ComputeSelect(scopedCtx)) { yield return(atom); } } }
public override async Task GenerateOutputs(EvaluationContext ctx) { _listCandidate ??= TemplexBase.Parse(ListExpression); if (_listCandidate != null) { var listObj = (await _listCandidate.Evaluate(ctx)) ?? new List <object>(); if (listObj is IList list) { foreach (var listItem in list) { // Initialize new evaluation context with the new variable in it var scopedCtx = ctx.Clone(); scopedCtx.SetLocalVariable(IteratorVariableName, new EvaluationVariable( evalAsync: () => Task.FromResult(listItem), selectResolver: () => AsyncUtil.Empty <Path>(), // It doesn't matter when generating output pathsResolver: () => AsyncUtil.Empty <Path>() // It doesn't matter when generating output )); // Run the template again on that context await Inner.GenerateOutputs(scopedCtx); } } else { throw new TemplateException($"Expression does not evaluate to a list ({_listCandidate})."); } } }
/// <summary> /// Clones the <see cref="EvaluationContext"/> and returns a new one that contains the new variable. /// </summary> private EvaluationContext GetScopeLocalContext(EvaluationContext ctx) { _varExpression ??= TemplexBase.Parse(VariableExpression); var variable = new EvaluationVariable( evalAsync: () => _varExpression.Evaluate(ctx), selectResolver: () => _varExpression.ComputeSelect(ctx), pathsResolver: () => _varExpression.ComputePaths(ctx)); var ctxClone = ctx.Clone(); ctxClone.SetLocalVariable(VariableName, variable); return(ctxClone); }
public override async IAsyncEnumerable <Path> ComputeSelect(EvaluationContext ctx) { _conditionCandidate ??= TemplexBase.Parse(ConditionExpression); if (_conditionCandidate != null && Inner != null) { await foreach (var select in _conditionCandidate.ComputeSelect(ctx)) { yield return(select); } await foreach (var select in Inner.ComputeSelect(ctx)) { yield return(select); } } }
public override async Task GenerateOutputs(EvaluationContext ctx) { _conditionCandidate ??= TemplexBase.Parse(ConditionExpression); if (_conditionCandidate != null && Inner != null) { var conditionObj = (await _conditionCandidate.Evaluate(ctx)) ?? false; if (conditionObj is bool condition) { if (condition) { await Inner.GenerateOutputs(ctx); } } else { throw new TemplateException($"If expression could not be applied. Expression ({_conditionCandidate}) does not evaluate to a true or false."); } } }