Giter Club home page Giter Club logo

expressionengine's People

Contributors

pksorensen avatar thygesteffensen avatar tomoemp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

expressionengine's Issues

Feature : Function Expression Defintions

We had the following expression

    "expression": "@and(equal(length(formvalue(logicalName())[idx()]['cvr']),8),isDigits(formvalue(logicalName())[idx()]['cvr']))"

and wanted to simplify the whole formvalue(logicalName())[idx()]['cvr'] into a currentCellValue function and coded this up:

public class CurrentCellValueFunction : Function
    {
        private readonly ILogger _logger;
        private readonly ManifestAccessor _validationContext;
        private readonly FormDataAccessor _formDataAccessor;
        private readonly FormValueFunction _formValueFunction;
        private readonly IdxFunction _idxFunction;
        private readonly LogicalNameFunction _logicalNameFunction;

        public CurrentCellValueFunction(
            ILogger<CurrentCellValueFunction> logger,
            ManifestAccessor validationContext,
            FormDataAccessor formDataAccessor,
            FormValueFunction formValueFunction,
            IdxFunction idxFunction,
            LogicalNameFunction logicalNameFunction) : base("currentCellValue")
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _validationContext = validationContext ?? throw new ArgumentNullException(nameof(validationContext));
            _formDataAccessor = formDataAccessor ?? throw new ArgumentNullException(nameof(formDataAccessor));
            _formValueFunction = formValueFunction;
            _idxFunction = idxFunction;
            _logicalNameFunction = logicalNameFunction;
        }

        public override async ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
        {
            _logger.LogDebug("{FunctionName} entered", nameof(CurrentCellValueFunction));
             
            try
            {  
                
                //currentCellValue = formvalue(logicalName())[idx()]['cvr']

                var logicalName = await _logicalNameFunction.ExecuteFunction();
                var idx = await _idxFunction.ExecuteFunction();
                var formvalue = await _formValueFunction.ExecuteFunction(logicalName);

                var currentCell = formvalue[idx.GetValue<int>()][_validationContext.CurrentAttributeLogicalName];

                return currentCell;

            }
            catch (Exception ex)
            {
                _logger.LogDebug(ex,"{FunctionName} failed", nameof(CurrentCellValueFunction));
                throw;
            }
        }
    }

however it bascially could have been automated in the framework to do Function expression Definitions:

services.AddFunctionExpresssionDefinition("currentCellValue", "@formvalue(logicalName())[idx()][attributeLogicalName()]")

or

services.AddFunctionExpresssionDefinition("currentCellValue", "formvalue(logicalName())[idx()][attributeLogicalName()]")

Feature: Implicit Conversions/Cast on ValueContainer

Would be nice to have implicit casts / conversions for ValueContainer, simplifying constructing a ValueContainer like below:


        public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
        {
            var relationship = parameters[0]?.ToString();


            return new ValueTask<ValueContainer>(new ValueContainer(relationship));

        }

with implicit conversions between simple types and ValueContainer one might do this instead

        public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
        {
            var relationship = parameters[0]?.ToString();


            return new ValueTask<ValueContainer>(relationship);

        }

Feature: Better Array support of ValueContainer

In the below example, getting the values of the array ValueContainer type is abit bloated and requires one to explicite do GetValue<IList<ValueContainer>>(), using ValueContainer[] or Object[] would throw exceptions.

        public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
        {
            var relationship = parameters[0]?.ToString()?.ToLower();
            var data = _formDataAccessor.Data;

            if (data.ContainsKey(relationship))
            {
                var array = data[relationship];
                if(array.Type() == ValueType.Array)
                {
                    var arrayData = array.GetValue<IList<ValueContainer>>();
                    return new ValueTask<ValueContainer>(new ValueContainer(arrayData.Count > 0));
                }
            }


            return new ValueTask<ValueContainer>(new ValueContainer(false));

        }

consider ValueContainer to implement IEnumerable ? as short cuts to return properties for objects or items for arrays. Or just a better AsArray?

concat function documentation wrong

The concat function only takes strings according to the documentaiton, however it works on every type.

Go through types and their generated string and update PrettyPrint, maybe look into replacing prettyprint with toString.

Go through string functions to see if there are more errors.

Function should be lazy

Consider the if function, ale three parameters are evaluated, the guard, true and false branch.
But consider the case where the false branch is guarded by the guard, but is evaluated anyways because it is not short circuit.

Consider changing this to object - CLR TYPE

Consider changing this to object - CLR TYPE

private readonly dynamic _value; // TODO: Consider changing this to object - CLR TYPE

    public class ValueContainer : IComparable, IEquatable<ValueContainer>
    {
        private readonly dynamic _value; // TODO: Consider changing this to object - CLR TYPE
        private readonly ValueType _type;

        public ValueContainer(string value, bool tryToParse = false)
ndex 8b1553e..093837d 100644
++ b/Test/ExpressionGrammarTest.cs

b36f84e1c85b68a55aabc64cf7c9cdd7c53a2a1a

- fix real async

  • fix real async

                        from preFix in allowedString
                        from exp in enclosedExpression.Optional()
                        select exp.IsEmpty ? preFix : preFix + exp.Get().Result)
                    // TODO - fix real async
                    // @assignees: thygesteffensen
                    .Many()
                select Task.FromResult(new ValueContainer(string.Concat(e)));

446caa3703632f1ad99360dcdb375bcead2468c3

Replace IEnumerable<IFunction> to IEnumerable<FunctionMetaData> instead

In ExpressionRule.cs use metadata and service provider to resolve functions, instead of resolving every function. Prior, functions were cheap to create due to their simple logic, new functions may contain HTTP clients or DB clients, which are more expensive to create. To make it faster and lighter, we can instead use mete data classes to locate a function and resolve it. See AddPlugin

Issues with dot indexing

When using dot indexing, the parser does not stop when meeting a comma ,, when using a dotindexing inside a function call, it keeps reading the other arguments, as a part of the dot indexing

Adding common functions which are not a part of Power Automate, such as pow() or sqrt()

The format and basic function offering are based heavily on Power Automate and I think we should keep it that way.

However, to the purpose of this project is to have functionality used by PowerAutomateMockUp and to make it easier for others to use the same expressions in their projects, why it is a standalone project.

To not break the Power Automate version and to still offer simple functions to other users, we could add an extension NuGet, where some extra functions could be added to the Dependency Injection, such as pow() or sqrt(). This could be done by:

// ...
services.AddExpressionEngine();
services.AddExpressionEngineExtensions();3
// ...

Then AddExpressionEngineExtensions could be located in Delegate.ExpressionEngine.Extensions namespace.

@pksorensen what do you think?

- fix real async

  • fix real async

                        from preFix in allowedString
                        from exp in enclosedExpression.Optional()
                        select exp.IsEmpty ? preFix : preFix + exp.Get().Result)
                    // TODO - fix real async
                    // @assignees: thygesteffensen
                    .Many()
                select Task.FromResult(new ValueContainer(string.Concat(e)));

32dc81a18f6684e0246a73740c88f0e96fa92ea6

Can not parse expression

Description

No matter how the expression is written, it will output as it is

Reproduction Steps

Using Visual Studio 2022 create ASP.NET Core Web / .Net 6.0 and install Delegate.ExpressionEngine 4.1.2

Code :

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
var services = new ServiceCollection();
services.AddExpressionEngine();
var sp = services.BuildServiceProvider();
var ee = sp.GetRequiredService<IExpressionEngine>();
var str = ee.Parse("1 + 1").Result;
Console.WriteLine(str); // output "1 + 1"
app.Run();

Expected behavior

2

Actual behavior

1 + 1

Configuration

  • Visual Studio 2022
  • .Net 6.0
  • Windows 10 21H2 / x64
  • Delegate.ExpressionEngine 4.1.2

Other information

The .csproj is :

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Delegate.ExpressionEngine" Version="4.1.2" />
  </ItemGroup>

</Project>

Negative numbers are not parsed correctly

@mul(10,-1) are not parsed correctly and the same string is returned, i.e. the parsing is incomplete.

  • Fix parsing of negative numbers
  • Add functionality to throw errors when parsing is incomplete

Incomplete parsing
How do we detect incomplete parsing? An exception shouldn't be thrown just because no expression is in the input string, but if a string contains the @{ and no } or if there's an error in-between, should an exception be thrown?

Feature : Alias Map

We based alot of functions of Power Automate, which makes sense. But generally writing my expressions i write eq() as a shorthand for equal.

Would properly be good to be able to just rename or alias functions in a project without having to implement it again.

I suggest we implement a service that can registered to map one function name to another.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.