Exemplo n.º 1
0
        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}).");
                }
            }
        }
Exemplo n.º 2
0
        public override IAsyncEnumerable <Path> ComputePaths(EvaluationContext ctx)
        {
            bool found = ctx.TryGetVariable(VariableName, out TemplateVariable variableEntry);

            return(found ?
                   variableEntry.ResolvePaths() :
                   AsyncUtil.Empty <Path>());
        }
Exemplo n.º 3
0
 /// <summary>
 /// If the <see cref="EvaluationFunction"/> returns an model <see cref="Entity"/>, this function returns
 /// the possible <see cref="Path"/>s leading to the returned <see cref="Entity"/>. The result is computed in
 /// the form of <see cref="IEnumerable{Path}"/>.
 /// A static <see cref="EvaluationContext"/> is provided in case some of the arguments had to be evaluated
 /// before calling the APIs in order to compute the required paths.
 /// A static <see cref="EvaluationContext"/> is one where any function that accesses an API or any variable that
 /// should be populated by model entities retrieved from an API will throw exceptions if invoked/accessed.
 /// </summary>
 /// <param name="args">The list of un-evaluated function arguments.</param>
 /// <param name="ctx">The static <see cref="EvaluationContext"/>.</param>
 public IAsyncEnumerable <Path> ComputePaths(TemplexBase[] args, EvaluationContext ctx)
 {
     if (_pathsResolver != null)
     {
         return(_pathsResolver.Invoke(args, ctx));
     }
     else
     {
         return(AsyncUtil.Empty <Path>());
     }
 }
Exemplo n.º 4
0
        public override IAsyncEnumerable <Path> ComputeSelect(EvaluationContext ctx)
        {
            if (Template == null)
            {
                return(AsyncUtil.Empty <Path>());
            }

            var scopedCtx = GetScopeLocalContext(ctx);

            return(Template.ComputeSelect(scopedCtx));
        }
Exemplo n.º 5
0
 /// <summary>
 /// If the variable contains a model <see cref="Entity"/>, this function should return the base
 /// <see cref="Path"/>(s) of this entity, which include the <see cref="QueryInfo"/> it will be loaded from
 /// </summary>
 public IAsyncEnumerable <Path> ResolvePaths()
 {
     if (_pathsResolver != null)
     {
         return(_pathsResolver.Invoke());
     }
     else
     {
         return(AsyncUtil.Empty <Path>());
     }
 }
Exemplo n.º 6
0
 /// <summary>
 /// Compute the list of API calls and SELECTs (in the form of <see cref="IEnumerable{Path}"/>) that are
 /// needed for <see cref="Evaluate()"/> to run correctly.
 /// </summary>
 public IAsyncEnumerable <Path> ResolveSelect()
 {
     if (_selectResolver != null)
     {
         return(_selectResolver.Invoke());
     }
     else
     {
         return(AsyncUtil.Empty <Path>());
     }
 }
Exemplo n.º 7
0
        public override async Task GenerateOutput(StringBuilder builder, EvaluationContext ctx, Func <string, string> encodeFunc = null)
        {
            if (ListCandidate != null && Template != null)
            {
                var listObj = (await ListCandidate.Evaluate(ctx)) ?? new List <object>();
                if (listObj is IList list)
                {
                    int index = 0;
                    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
                                                       ));

                        // Index, useful for setting line numbers
                        scopedCtx.SetLocalVariable(IteratorVariableName + "_index", new EvaluationVariable(
                                                       evalAsync: () => Task.FromResult <object>(index),
                                                       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 Template.GenerateOutput(builder, scopedCtx, encodeFunc);

                        index++;
                    }
                }
                else
                {
                    throw new TemplateException($"Foreach expression could not be applied. Expression ({ListCandidate}) does not evaluate to a list.");
                }
            }
        }
Exemplo n.º 8
0
 public override IAsyncEnumerable <Path> ComputePaths(EvaluationContext ctx)
 {
     return(AsyncUtil.Empty <Path>());
 }
Exemplo n.º 9
0
 public override IAsyncEnumerable <Path> ComputePaths(EvaluationContext ctx)
 {
     // Constants aren't based on any paths
     return(AsyncUtil.Empty <Path>());
 }
Exemplo n.º 10
0
 public override IAsyncEnumerable <Path> ComputeSelect(EvaluationContext ctx)
 {
     // Constants don't need any select
     return(AsyncUtil.Empty <Path>());
 }