Packages
expression
2.42.1
2.49.1
2.49.0
2.48.0
2.47.5
2.47.4
2.47.3
2.47.2
2.47.1
2.47.0
2.46.0
2.45.1
2.45.0
2.44.1
2.44.0
2.43.0
2.42.1
2.41.4
2.41.3
2.41.2
2.41.0
2.40.0
2.38.0
2.37.0
2.36.2
2.36.1
2.36.0
2.35.0
2.34.0
2.33.1
2.33.0
2.32.1
2.31.6
2.31.3
2.31.0
2.30.0
2.28.0
2.27.3
2.27.2
2.27.1
2.27.0
2.26.1
2.26.0
2.25.0
2.24.2
2.24.1
2.24.0
2.23.9
2.23.8
2.23.7
2.23.6
2.23.4
2.23.3
2.23.2
2.23.1
2.23.0
2.22.2
2.22.0
2.21.0
2.20.0
2.19.0
2.18.0
2.17.0
2.16.0
2.14.0
2.13.0
2.12.0
2.11.0
2.10.1
2.10.0
2.9.0
2.8.0
2.6.0
2.5.8
2.5.7
2.5.6
2.5.5
2.5.4
2.5.3
2.5.2
2.5.1
2.5.0
2.4.1
2.4.0
2.3.2
2.3.1
2.3.0
2.2.1
2.2.0
2.1.1
2.1.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.1.1
1.1.0
1.0.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.0
0.4.3
0.4.2
0.4.1
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.1.0
A Excel like expression parser, compatible with FLOIP Expression language.
Current section
Files
Jump to
Current section
Files
expression
README.md
README.md
# ExpressionAn Elixir library implementing the [FLOIP Expressions](https://floip.gitbook.io/flow-specification/expressions) language.```elixiriex(1)> Expression.evaluate!("Hello @name", %{...(1)> "name" => "World"...(1)> })["Hello ", "World"]iex(2)> Expression.evaluate("Hello @contact.name", %{...(2)> "contact" => %{...(2)> "name" => "peter"...(2)> }...(2)> }){:ok, ["Hello ", "peter"]}iex(6)> Expression.evaluate("Hello @contact.name, you were born in @(YEAR(contact.birthday))", %{...(6)> "contact" => %{...(6)> "name" => "mary",...(6)> "birthday" => "1920-02-02T00:00:00"...(6)> }...(6)> }){:ok, ["Hello ", "mary", ", you were born in ", 1920]}iex(7)> Expression.evaluate("Hello @PROPER(contact.name)", %{...(7)> "contact" => %{...(7)> "name" => "peter rabbit"...(7)> }...(7)> }){:ok, ["Hello ", "Peter Rabbit"]}ex(8)> Expression.evaluate("Your next appointment is @(EDATE(contact.appointment, 1))", %{...(8)> "contact" => %{...(8)> "appointment" => DateTime.utc_now()...(8)> }...(8)> }){:ok, ["Your next appointment is ", ~U[2022-06-25 08:39:51.730780Z]]}iex(9)> Expression.evaluate("Your next appointment is @(DATEVALUE(EDATE(contact.appointment, 1), \"%Y-%m-%d\"))", %{...(9)> "contact" => %{...(9)> "appointment" => "2020-12-13T23:35:55"...(9)> }...(9)> }){:ok, ["Your next appointment is ", "2021-01-13"]}iex(10)> Expression.evaluate("Dear @IF(contact.gender = 'M', 'Sir', 'Client')", %{...(10)> "contact" => %{...(10)> "gender" => "O"...(10)> }...(10)> }){:ok, ["Dear ", "Client"]}```The values of each chunk (either text or expression) is in the list returned by evaluate.The return values of Expressions are typed. The types are documented below under _Types_.If you're looking for a shorthand to convert these to a single string output use `Expression.evaluate_as_string!/3`.```elixiriex(11)> Expression.evaluate_as_string!("Your next appointment is @(DATEVALUE(EDATE(contact.appointment, 1), \"%Y-%m-%d\"))", %{...(11)> "contact" => %{...(11)> "appointment" => "2020-12-13T23:35:55"...(11)> }...(11)> })"Your next appointment is 2021-01-13"```See `Engaged.Callbacks` for all the functions implemented.Often, when one has an email address in an expression, one would want to leave it as is.Expressions accommodates this by having expressions that evaluate to nil left as is.```elixiriex(3)> Expression.evaluate_as_string!("info@support.com")"info@support.com"```A thing to note though is that if `@support.com` does resolve to something with the given context,it will still be applied:```elixiriex(6)> Expression.evaluate_as_string!("info@support.com", %{...(6)> "support" => %{...(6)> "com" => "example placeholder value"...(6)> }...(6)> })"infoexample placeholder value"```To properly escape the `@`, prefix it with another `@` as the example below:```elixiriex(4)> Expression.evaluate_as_string!("info@@support.com")"info@support.com"```# TypesExpression knows the following types:```elixiriex> # Floatsiex> Expression.evaluate("@(1.23)"){:ok, [1.23}iex> # Integersiex> Expression.evaluate("@(1)"){:ok, [1]}iex> # DateTime in ISO and a sloppy US formatsiex> Expression.evaluate("@(2020-12-13T23:35:55)"){:ok, [~U[2020-12-13 23:35:55.0Z]]}iex> Expression.evaluate("@(13-12-2020 23:35:55)"){:ok, [~U[2020-12-13 23:35:55Z]]}iex> # case insensitive booleansiex> Expression.evaluate("@(true)"){:ok, [true]}iex> Expression.evaluate("@(TrUe)"){:ok, [true]}iex> Expression.evaluate("@(false)"){:ok, [false]}iex> Expression.evaluate("@(FaLsE)"){:ok, [false]}```# Future extensions- It may be worth implementing a binary only expression parser, something that is guaranteed to only return a `true` or `false`. That could be useful when building decision trees with dynamic conditionals depending on context.## Installation> This is not available in Hex.pm or Hexdocs.pm yetIf [available in Hex](https://hex.pm/docs/publish), the package can be installedby adding `expression` to your list of dependencies in `mix.exs`:```elixirdef deps do [ {:expression, "~> 2.42.1"} ]end```## Doing releasesUse the Github UI to create a new release and publish it. Make sure to update the`mix.exs` and `README.md` version references _before_ publishing otherwise hex.pmwill complain and prevent you from publishing over an already existing releasedversion.## DocumentationDocumentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)and published on [HexDocs](https://hexdocs.pm). Once published, the docs canbe found at [https://hexdocs.pm/expression](https://hexdocs.pm/expression).