From 01e4ceb0546088e8956707350d344da960667d36 Mon Sep 17 00:00:00 2001 From: algorithmiker <104317939+algorithmiker@users.noreply.github.com> Date: Sat, 10 Jan 2026 21:52:27 +0100 Subject: [PATCH] finish Lua API docs. --- docs/usage-gui.md | 3 +- entrace_query/api-docs/en_as_string.md | 11 +- entrace_query/api-docs/en_attr_by_idx.md | 11 ++ entrace_query/api-docs/en_attr_by_name.md | 11 ++ entrace_query/api-docs/en_attr_name.md | 11 ++ entrace_query/api-docs/en_attr_names.md | 13 ++ entrace_query/api-docs/en_attr_value.md | 11 ++ entrace_query/api-docs/en_attr_values.md | 13 ++ entrace_query/api-docs/en_attrs.md | 11 ++ entrace_query/api-docs/en_child_cnt.md | 10 ++ entrace_query/api-docs/en_children.md | 13 ++ .../api-docs/en_contains_anywhere.md | 13 ++ entrace_query/api-docs/en_filter.md | 23 ++-- entrace_query/api-docs/en_filterset_dnf.md | 50 +++---- .../api-docs/en_filterset_from_list.md | 18 +-- .../api-docs/en_filterset_from_range.md | 19 +-- .../api-docs/en_filterset_intersect.md | 46 ++----- .../api-docs/en_filterset_materialize.md | 18 ++- entrace_query/api-docs/en_filterset_not.md | 14 +- entrace_query/api-docs/en_filterset_union.md | 44 ++----- entrace_query/api-docs/en_join.md | 34 ++++- entrace_query/api-docs/en_metadata_file.md | 10 ++ entrace_query/api-docs/en_metadata_level.md | 10 ++ entrace_query/api-docs/en_metadata_line.md | 10 ++ .../api-docs/en_metadata_module_path.md | 10 ++ entrace_query/api-docs/en_metadata_name.md | 10 ++ entrace_query/api-docs/en_metadata_table.md | 17 +++ entrace_query/api-docs/en_metadata_target.md | 10 ++ entrace_query/api-docs/en_span_cnt.md | 10 ++ entrace_query/build.rs | 46 ++++--- entrace_query/src/lua_api.rs | 123 ++++++++++++++++++ 31 files changed, 497 insertions(+), 156 deletions(-) diff --git a/docs/usage-gui.md b/docs/usage-gui.md index 8f57fe2..de917a8 100644 --- a/docs/usage-gui.md +++ b/docs/usage-gui.md @@ -51,7 +51,8 @@ The methods to work with the query data are likewise prefixed by `en_`. ### Example queries There are some example queries in [`example_query.lua`](../example_query.lua) in the repo root. ### Available API -The full API documentation for ENTRACE can be found in the [search module docs](../gui/src/search/lua_api.rs). +The full API documentation for ENTRACE can be found in the [LUa API Docs](../entrace_query/api-docs/). +Displaying the docs is also available in the GUI. Every function whose name starts with `en_` here implements a lua method for queries. ### Disabling parallelism diff --git a/entrace_query/api-docs/en_as_string.md b/entrace_query/api-docs/en_as_string.md index 3a50630..c98b5ca 100644 --- a/entrace_query/api-docs/en_as_string.md +++ b/entrace_query/api-docs/en_as_string.md @@ -1,2 +1,11 @@ -Return a reasonable string representation of the entry at id. +Return a string representation of the entry at id. The format of this string should be considered unstable. + +## INPUT +A span id. + +## OUTPUT +A string. + +## EXAMPLE +local s = en_as_string(id) diff --git a/entrace_query/api-docs/en_attr_by_idx.md b/entrace_query/api-docs/en_attr_by_idx.md index e69de29..08cbe31 100644 --- a/entrace_query/api-docs/en_attr_by_idx.md +++ b/entrace_query/api-docs/en_attr_by_idx.md @@ -0,0 +1,11 @@ +Get an attribute name and value by its index. + +## INPUT +- A span id. +- The attribute index (an integer, which starts counting from 0). + +## OUTPUT +The attribute name (string) and its value. + +## EXAMPLE +local name, value = en_attr_by_idx(id, 0) diff --git a/entrace_query/api-docs/en_attr_by_name.md b/entrace_query/api-docs/en_attr_by_name.md index e69de29..1a91bb7 100644 --- a/entrace_query/api-docs/en_attr_by_name.md +++ b/entrace_query/api-docs/en_attr_by_name.md @@ -0,0 +1,11 @@ +Get the value of an attribute by its name. + +## INPUT +- A span id. +- The attribute name (a string). + +## OUTPUT +The attribute value, or nil. + +## EXAMPLE +local value = en_attr_by_name(id, "my_attribute") diff --git a/entrace_query/api-docs/en_attr_name.md b/entrace_query/api-docs/en_attr_name.md index e69de29..fcfca92 100644 --- a/entrace_query/api-docs/en_attr_name.md +++ b/entrace_query/api-docs/en_attr_name.md @@ -0,0 +1,11 @@ +Get an attribute name by its index. + +## INPUT +- A span id. +- The attribute index (an int, which starts from 0). + +## OUTPUT +The attribute name (string). + +## EXAMPLE +local name = en_attr_name(id, 0) diff --git a/entrace_query/api-docs/en_attr_names.md b/entrace_query/api-docs/en_attr_names.md index e69de29..24095b2 100644 --- a/entrace_query/api-docs/en_attr_names.md +++ b/entrace_query/api-docs/en_attr_names.md @@ -0,0 +1,13 @@ +Get a list of attribute names for an entry. + +## INPUT +A span id. + +## OUTPUT +list[string] of attribute names. + +## EXAMPLE +local names = en_attr_names(id) +for i, name in ipairs(names) do + en_log(name) +end diff --git a/entrace_query/api-docs/en_attr_value.md b/entrace_query/api-docs/en_attr_value.md index e69de29..4c076bf 100644 --- a/entrace_query/api-docs/en_attr_value.md +++ b/entrace_query/api-docs/en_attr_value.md @@ -0,0 +1,11 @@ +Get an attribute value of a span by its index. + +## INPUT +- A span id. +- The attribute index: an int. This starts counting from 0. + +## OUTPUT +The attribute value. + +## EXAMPLE +local value = en_attr_value(id, 0) diff --git a/entrace_query/api-docs/en_attr_values.md b/entrace_query/api-docs/en_attr_values.md index e69de29..f9cd811 100644 --- a/entrace_query/api-docs/en_attr_values.md +++ b/entrace_query/api-docs/en_attr_values.md @@ -0,0 +1,13 @@ +Get a list of attribute values for an entry. + +## INPUT +A span id. + +## OUTPUT +list[object]: a list of attribute values. + +## EXAMPLE +local values = en_attr_values(id) +for i, value in ipairs(values) do + en_log(value) +end diff --git a/entrace_query/api-docs/en_attrs.md b/entrace_query/api-docs/en_attrs.md index e69de29..b9e3fe2 100644 --- a/entrace_query/api-docs/en_attrs.md +++ b/entrace_query/api-docs/en_attrs.md @@ -0,0 +1,11 @@ +Get attributes of an entry as a table. + +## INPUT +A span id. + +## OUTPUT +A table which maps attribute names to attribute values. + +## EXAMPLE +local attrs = en_attrs(id) +local value = attrs.my_attribute diff --git a/entrace_query/api-docs/en_child_cnt.md b/entrace_query/api-docs/en_child_cnt.md index e69de29..7d1e550 100644 --- a/entrace_query/api-docs/en_child_cnt.md +++ b/entrace_query/api-docs/en_child_cnt.md @@ -0,0 +1,10 @@ +Get the number of children for an entry. + +## INPUT +A span id. + +## OUTPUT +The child count (an int). + +## EXAMPLE +local count = en_child_cnt(id) diff --git a/entrace_query/api-docs/en_children.md b/entrace_query/api-docs/en_children.md index e69de29..a074e22 100644 --- a/entrace_query/api-docs/en_children.md +++ b/entrace_query/api-docs/en_children.md @@ -0,0 +1,13 @@ +Get the children of an entry. + +## INPUT +A span id. + +## OUTPUT +The list of children (list[int]). + +## EXAMPLE +local children = en_children(id) +for i, child_id in ipairs(children) do + en_log(child_id) +end diff --git a/entrace_query/api-docs/en_contains_anywhere.md b/entrace_query/api-docs/en_contains_anywhere.md index e69de29..482bdff 100644 --- a/entrace_query/api-docs/en_contains_anywhere.md +++ b/entrace_query/api-docs/en_contains_anywhere.md @@ -0,0 +1,13 @@ +Check if the string representation of an entry contains a given substring. + +## INPUT +- A span id. +- The substring to search for. + +## OUTPUT +Whether the substring appears in the entry. + +## EXAMPLE +if en_contains_anywhere(id, "error") then + en_log("Found error in entry " .. id) +end diff --git a/entrace_query/api-docs/en_filter.md b/entrace_query/api-docs/en_filter.md index 54bb84c..5d44fff 100644 --- a/entrace_query/api-docs/en_filter.md +++ b/entrace_query/api-docs/en_filter.md @@ -1,8 +1,15 @@ - en_filter() - input: - filter: table with - target: name of variable eg. "message" or "meta.filename" - relation: a relation, one of "EQ", "LT", "GT" - value: a constant to compare with - src: filterset - outputs: { type = "filterset", root = 1, items = { src = 0, {type = "rel_dnf", src = 0, clauses = {{ target, relation, value}} }}}, \ No newline at end of file +Apply a filter to a filterset to match only the spans matching a relation. + +## INPUT +- A table describing the relation: + - target: name of variable, eg. "message" or "meta.filename" + - relation: a string, one of "EQ" | "LT" | "GT" + - value: a constant to compare with. +- src: a filterset. + +## OUTPUT +A filterset that matches only the spans which satisfy the relation. + +## EXAMPLE +local fs = en_filterset_from_range(0, 100) +local filtered = en_filter({target = "meta.level", relation = "EQ", value = 5}, fs) \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_dnf.md b/entrace_query/api-docs/en_filterset_dnf.md index 59477a3..c106a7c 100644 --- a/entrace_query/api-docs/en_filterset_dnf.md +++ b/entrace_query/api-docs/en_filterset_dnf.md @@ -1,31 +1,19 @@ - en_filterset_dnf() - input: - filters: a list of list of filter descriptions, which is interpreted as a DNF clause list. - (this example would be (a=1 AND c=0) OR (b=1) - { - { - { target = "a", relation = "EQ", value = "1", src = 0 }, - { target = "c", relation = "EQ", value = "0", src = 0 }, - } - { - { target = "b", relation = "EQ", value = "1", src = 0}, - } - } - source: a filterset - outputs: a filterset that matches an item if satisfies either of the AND clauses - { type: "filterset", - root: 1, - items: { - { type = "prim_list", value = {1,2,3}}, - { type = "rel_dnf", src = 0, - clauses = { - { - { target = "a", relation = "EQ", value = "1", src = 0 }, - { target = "c", relation = "EQ", value = "0", src = 0 }, - } - { - { target = "b", relation = "EQ", value = "1", src = 0}, - } - } - } - } \ No newline at end of file +Apply a filter in Disjunctive Normal Form (OR of ANDs) to a filterset. + +## INPUT +- A clause list, where each clause is a list of filter descriptions accepted by en_filter. +Such a filter description is a table that looks like: + - target: name of variable, eg. "message" or "meta.filename" + - relation: a string, one of "EQ" | "LT" | "GT" + - value: a constant to compare with. +- A source filterset. + +## OUTPUT +A new filterset matching spans which satisfy the DNF. + +## EXAMPLE +local fs = en_filterset_from_range(0, 100) +local level_5_or_message_error = en_filterset_dnf({ + { {target="meta.level", relation="EQ", value=5} }, + { {target="message", relation="EQ", value="error"} } +}, fs) \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_from_list.md b/entrace_query/api-docs/en_filterset_from_list.md index 5be619a..794690f 100644 --- a/entrace_query/api-docs/en_filterset_from_list.md +++ b/entrace_query/api-docs/en_filterset_from_list.md @@ -1,8 +1,10 @@ - en_filterset_from_list() - input: list of ids - outputs: a table with - type: "filterset" - root: 0 - items: { - { type = "prim_list"; value = the list} - } \ No newline at end of file +Create a filterset from a list of span IDs. + +## INPUT +A list (sequence table) of span IDs. + +## OUTPUT +A filterset matching the provided spans. + +## EXAMPLE +local fs = en_filterset_from_list({1, 5, 10}) \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_from_range.md b/entrace_query/api-docs/en_filterset_from_range.md index 789e3c7..bed8087 100644 --- a/entrace_query/api-docs/en_filterset_from_range.md +++ b/entrace_query/api-docs/en_filterset_from_range.md @@ -1,8 +1,11 @@ - en_filterset_from_range() - input: start, end - outputs: a table with - type: "filterset" - root: 0 - items: { - { type = "prim_range"; start = start, end=end} - } \ No newline at end of file +Create a filterset from a range of span IDs. + +## INPUT +- start index (int) +- end index (int) + +## OUTPUT +A filterset matching all spans in [start, end]. + +## EXAMPLE +local fs = en_filterset_from_range(0, 100) \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_intersect.md b/entrace_query/api-docs/en_filterset_intersect.md index 6be3430..d114b7f 100644 --- a/entrace_query/api-docs/en_filterset_intersect.md +++ b/entrace_query/api-docs/en_filterset_intersect.md @@ -1,34 +1,12 @@ - en_filterset_intersect() - input: - filters: a list of filtersets, e. g - { - { type: "filterset", - root: 1, - items: { - { type = "prim_list", value = {1,2,3}}, - { type = "rel", target = "a", relation = "EQ", value = "1", src = 0 }, - } - } - { type: "filterset", - root: 1, - items: { - {type: "prim_list", value = {1,2,3} }, - {type: "rel", target = "b", relation = "EQ", value = "1", src = 0}, - } - } - } - outputs: a filterset that matches an item if it is in all input filtersets. - This does NOT deduplicate any items, eg. for the given inputs, the result would be as follows. - Note that en_materialize() MAY deduplicate, but there is no guarantee it will. (it currently - doesn't, because an acyclic graph is required for evauator correctness, this might change). - { type: "filterset", - root: 4, - items: { - { type = "prim_list", value = {1,2,3}}, - { type = "rel", target = "a", relation = "EQ", value = "1", src = 0 }, - { type: "prim_list", value = {1,2,3}}, - { type: "rel", target = "b", relation = "EQ", value = "1", src = 2 }, - { type: "intersect", srcs = { 1, 3 }} - } - Note: if you are intersecting filters on the same source filterset, en_filter_all will likely - be faster. \ No newline at end of file +Create a filterset that matches the intersection of multiple filtersets. + +## INPUT +A list of filtersets. + +## OUTPUT +A filterset that matches a span only if it is matched by all of the input filtersets. + +## EXAMPLE +local fs1 = en_filterset_from_range(0, 100) +local fs2 = en_filterset_from_range(50, 150) +local combined = en_filterset_intersect({fs1, fs2}) \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_materialize.md b/entrace_query/api-docs/en_filterset_materialize.md index b69d97c..d6374b1 100644 --- a/entrace_query/api-docs/en_filterset_materialize.md +++ b/entrace_query/api-docs/en_filterset_materialize.md @@ -1,3 +1,15 @@ - Materialize a filterset; which means going from the lazy representation of filters as a series - of operations into a concrete list of matching indices. - In some lazy languages, this operation is called "force". \ No newline at end of file +Materialize a filterset into a list of matching span IDs. +In some lazy languages, this operation is called *force*. + +## INPUT +A filterset. + +## OUTPUT +A list (sequence table) of span IDs. + +## EXAMPLE +local fs = en_filterset_from_range(0, 100) +local ids = en_filterset_materialize(fs) +for i, id in ipairs(ids) do + en_log(id) +end \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_not.md b/entrace_query/api-docs/en_filterset_not.md index 9c5ba68..cf936e9 100644 --- a/entrace_query/api-docs/en_filterset_not.md +++ b/entrace_query/api-docs/en_filterset_not.md @@ -1,3 +1,11 @@ - en_filterset_not() - input: filterset - outputs: a filterset that matches an item exactly if it is not in the filterset. \ No newline at end of file +Invert a filterset. + +## INPUT +A filterset. + +## OUTPUT +A filterset that matches all spans not matched by the input filterset. + +## EXAMPLE +local fs = en_filterset_from_range(0, 100) +local inverted = en_filterset_not(fs) \ No newline at end of file diff --git a/entrace_query/api-docs/en_filterset_union.md b/entrace_query/api-docs/en_filterset_union.md index 1b197d6..86640d3 100644 --- a/entrace_query/api-docs/en_filterset_union.md +++ b/entrace_query/api-docs/en_filterset_union.md @@ -1,34 +1,12 @@ - en_filterset_union() - input: - filters: a list of filtersets, e. g - { - { type: "filterset", - root: 1, - items: { - { type = "prim_list", value = {1,2,3}}, - { type = "rel", target = "a", relation = "EQ", value = "1", src = 0 }, - } - } - { type: "filterset", - root: 1, - items: { - {type: "prim_list", value = {1,2,3} }, - {type: "rel", target = "b", relation = "EQ", value = "1", src = 0}, - } - } - } - outputs: a filterset that matches an item if it is in any input filterset. - This does NOT deduplicate any items, eg. for the given inputs, the result would be as follows. - Note that en_materialize() MAY deduplicate, but there is no guarantee it will. - { type: "filterset", - root: 4, - items: { - { type = "prim_list", value = {1,2,3}}, - { type = "rel", target = "a", relation = "EQ", value = "1", src = 0 }, - { type: "prim_list", value = {1,2,3}}, - { type: "rel", target = "b", relation = "EQ", value = "1", src = 2 }, - { type: "union", srcs = { 1, 3 }} - } +Create a filterset that matches the union of multiple filtersets. - Note: if you are unioning filters on the same source filterset, en_filter_any will likely - be faster. \ No newline at end of file +## INPUT +A list of filtersets. + +## OUTPUT +A filterset that matches a span if it is matched by any of the input filtersets. + +## EXAMPLE +local fs1 = en_filterset_from_range(0, 10) +local fs2 = en_filterset_from_range(20, 30) +local combined = en_filterset_union({fs1, fs2}) \ No newline at end of file diff --git a/entrace_query/api-docs/en_join.md b/entrace_query/api-docs/en_join.md index c37c883..9d0d9b3 100644 --- a/entrace_query/api-docs/en_join.md +++ b/entrace_query/api-docs/en_join.md @@ -1,7 +1,29 @@ - en_join lets you switch from N threads to one thread. - all threads which reach the en_join point will be shut down, except for the last one. - the last one gets all the ids from other threads. +Switch from N threads to one thread. - This is useful for map-reduce type computations where the first part of the operation can be - parallelized, but we need serial execution on the last part; - for example if you want to sort the returned spans. \ No newline at end of file +All query threads that reach the en_join point are shut down, except for the last one. +This last thread receives a concatenated list of IDs submitted by all threads. + +This is useful for map-reduce type computations where the first part of the operation can be +parallelized, but we need serial execution on the last part; +for example if you want to sort the returned spans. + +## INPUT +A list (sequence table) of span IDs. + +## OUTPUT +A combined list of span IDs if this is the last thread to finish, otherwise the thread shuts down. + +## EXAMPLE +local rstart, rend = en_span_range() +local ids = {} +for i=rstart,rend do + table.insert(ids,i) +end +local total_ids = en_join(ids) + +-- Sort the combined results by name +table.sort(total_ids, function(a, b) + return en_metadata_name(a) < en_metadata_name(b) +end) + +return total_ids \ No newline at end of file diff --git a/entrace_query/api-docs/en_metadata_file.md b/entrace_query/api-docs/en_metadata_file.md index e69de29..f97cacf 100644 --- a/entrace_query/api-docs/en_metadata_file.md +++ b/entrace_query/api-docs/en_metadata_file.md @@ -0,0 +1,10 @@ +Get the source file path of an entry. + +## INPUT +A span id. + +## OUTPUT +A string containing the file path, or nil. + +## EXAMPLE +local file = en_metadata_file(id) diff --git a/entrace_query/api-docs/en_metadata_level.md b/entrace_query/api-docs/en_metadata_level.md index e69de29..ebf1365 100644 --- a/entrace_query/api-docs/en_metadata_level.md +++ b/entrace_query/api-docs/en_metadata_level.md @@ -0,0 +1,10 @@ +Get the log level of an entry. + +## INPUT +A span id. + +## OUTPUT +An integer representing the level: 1=Trace, 2=Debug, 3=Info, 4=Warn, 5=Error. + +## EXAMPLE +local level = en_metadata_level(id) diff --git a/entrace_query/api-docs/en_metadata_line.md b/entrace_query/api-docs/en_metadata_line.md index e69de29..12bb8a0 100644 --- a/entrace_query/api-docs/en_metadata_line.md +++ b/entrace_query/api-docs/en_metadata_line.md @@ -0,0 +1,10 @@ +Get the source line number of an entry. + +## INPUT +A span id. + +## OUTPUT +An integer representing the line number, or nil. + +## EXAMPLE +local line = en_metadata_line(id) diff --git a/entrace_query/api-docs/en_metadata_module_path.md b/entrace_query/api-docs/en_metadata_module_path.md index e69de29..a462f37 100644 --- a/entrace_query/api-docs/en_metadata_module_path.md +++ b/entrace_query/api-docs/en_metadata_module_path.md @@ -0,0 +1,10 @@ +Get the module path of an entry. + +## INPUT +A span id. + +## OUTPUT +The module path as a string, or nil. + +## EXAMPLE +local path = en_metadata_module_path(id) diff --git a/entrace_query/api-docs/en_metadata_name.md b/entrace_query/api-docs/en_metadata_name.md index e69de29..b4457d8 100644 --- a/entrace_query/api-docs/en_metadata_name.md +++ b/entrace_query/api-docs/en_metadata_name.md @@ -0,0 +1,10 @@ +Get the name of an entry. + +## INPUT +A span id. + +## OUTPUT +The name (string). + +## EXAMPLE +local name = en_metadata_name(id) \ No newline at end of file diff --git a/entrace_query/api-docs/en_metadata_table.md b/entrace_query/api-docs/en_metadata_table.md index e69de29..1b52f78 100644 --- a/entrace_query/api-docs/en_metadata_table.md +++ b/entrace_query/api-docs/en_metadata_table.md @@ -0,0 +1,17 @@ +Get metadata of a span. + +## INPUT +A span id. + +## OUTPUT +A table: +- name: string +- level: int (1=Trace, 2=Debug, 3=Info, 4=Warn, 5=Error) +- file: string or nil +- line: int or nil +- target: string +- module_path: string or nil + +## EXAMPLE +local meta = en_metadata_table(id) +en_log(meta.name) \ No newline at end of file diff --git a/entrace_query/api-docs/en_metadata_target.md b/entrace_query/api-docs/en_metadata_target.md index e69de29..a165027 100644 --- a/entrace_query/api-docs/en_metadata_target.md +++ b/entrace_query/api-docs/en_metadata_target.md @@ -0,0 +1,10 @@ +Get the target of an entry. + +## INPUT +A span id. + +## OUTPUT +The target as a string. + +## EXAMPLE +local target = en_metadata_target(id) diff --git a/entrace_query/api-docs/en_span_cnt.md b/entrace_query/api-docs/en_span_cnt.md index e69de29..897170f 100644 --- a/entrace_query/api-docs/en_span_cnt.md +++ b/entrace_query/api-docs/en_span_cnt.md @@ -0,0 +1,10 @@ +Get the total number of spans in the file. + +## INPUT +Nothing. + +## OUTPUT +Number of spans (an int). + +## EXAMPLE +local count = en_span_cnt() \ No newline at end of file diff --git a/entrace_query/build.rs b/entrace_query/build.rs index 9945960..f95acfd 100644 --- a/entrace_query/build.rs +++ b/entrace_query/build.rs @@ -36,7 +36,7 @@ fn main() { }; let doc = doc.trim().to_string(); if let Err(msg) = validate_docs(&doc) { - println!("cargo::warning=Validation failed for {}: {msg}", file_path.display()); + println!("cargo::error=Validation failed for {}: {msg}", file_path.display()); }; fns.push(Function { name: name.clone(), docs: doc }); } @@ -89,25 +89,31 @@ pub fn api_fn_names(items: &[Item]) -> impl Iterator { // blah // ## EXAMPLE // local bar = en_function_name(1, "foo") -pub fn validate_docs(inp: &str) -> Result<(), &'static str> { - let lines: Vec<&str> = inp.lines().collect(); - let _ = lines - .iter() - .enumerate() - .find(|(_i, x)| x.starts_with("## INPUT")) - .ok_or("there should be a subheading ## INPUT")?; - let _ = lines - .iter() - .enumerate() - .find(|(_i, x)| x.starts_with("## OUTPUT")) - .ok_or("there should be a subheading ## OUTPUT")?; - let _ = lines - .iter() - .enumerate() - .find(|(_i, x)| x.starts_with("## EXAMPLE")) - .ok_or("there should be a subheading ## EXAMPLE")?; - - Ok(()) +pub fn validate_docs(inp: &str) -> Result<(), String> { + let (mut input_fnd, mut output_fnd, mut example_fnd) = (false, false, false); + for line in inp.lines() { + if line.starts_with("## INPUT") { + input_fnd = true; + } + if line.starts_with("## OUTPUT") { + output_fnd = true; + } + if line.starts_with("## EXAMPLE") { + example_fnd = true; + } + } + if input_fnd && output_fnd && example_fnd { + return Ok(()); + } + let mut err = String::from("Expected to find subheading(s): "); + for (found, s) in [(input_fnd, "INPUT"), (output_fnd, "OUTPUT"), (example_fnd, "EXAMPLE")] { + if !found { + err.push_str(s); + err.push(','); + } + } + err.pop(); + Err(err) } //fn find_subheading(lines: &[&str]) -> Option{ diff --git a/entrace_query/src/lua_api.rs b/entrace_query/src/lua_api.rs index b366937..b35b6e1 100644 --- a/entrace_query/src/lua_api.rs +++ b/entrace_query/src/lua_api.rs @@ -391,6 +391,15 @@ pub fn span_matches_filter( // // Valid item types are: "prim_list", "prim_range", "rel_dnf", // "intersect", "union", "invert" + +// en_filterset_from_list() +// input: list of ids +// outputs: a table with +// type: "filterset" +// root: 0 +// items: { +// { type = "prim_list"; value = the list} +// } #[doc = include_str!("../api-docs/en_filterset_from_list.md")] pub fn en_filterset_from_list(lua: &Lua, t: Table) -> mlua::Result { let fs = lua.create_table()?; @@ -407,6 +416,14 @@ pub fn en_filterset_from_list(lua: &Lua, t: Table) -> mlua::Result
{ Ok(fs) } +// en_filterset_from_range() +// input: start, end +// outputs: a table with +// type: "filterset" +// root: 0 +// items: { +// { type = "prim_range"; start = start, end=end} +// } #[doc = include_str!("../api-docs/en_filterset_from_range.md")] pub fn en_filterset_from_range(lua: &Lua, (start, end): (usize, usize)) -> mlua::Result
{ let fs = lua.create_table()?; @@ -424,6 +441,14 @@ pub fn en_filterset_from_range(lua: &Lua, (start, end): (usize, usize)) -> mlua: Ok(fs) } +// en_filter() +// input: +// filter: table with +// target: name of variable eg. "message" or "meta.filename" +// relation: a relation, one of "EQ", "LT", "GT" +// value: a constant to compare with +// src: filterset +// outputs: { type = "filterset", root = 1, items = { src = 0, {type = "rel_dnf", src = 0, clauses = {{ target, relation, value}} }}}, #[doc = include_str!("../api-docs/en_filter.md")] pub fn en_filter(lua: &Lua, (filter, src): (Table, Table)) -> mlua::Result
{ let old_items: Table = src.get("items")?; @@ -488,6 +513,38 @@ fn concat_items_lists(lua: &Lua, filters: Table) -> mlua::Result<(Table, Vec mlua::Result
{ let fs = lua.create_table()?; @@ -502,6 +559,38 @@ pub fn en_filterset_union(lua: &Lua, filters: Table) -> mlua::Result
{ Ok(fs) } +// en_filterset_intersect() +// input: +// filters: a list of filtersets, e. g +// { +// { type: "filterset", +// root: 1, +// items: { +// { type = "prim_list", value = {1,2,3}}, +// { type = "rel", target = "a", relation = "EQ", value = "1", src = 0 }, +// } +// } +// { type: "filterset", +// root: 1, +// items: { +// {type: "prim_list", value = {1,2,3} }, +// {type: "rel", target = "b", relation = "EQ", value = "1", src = 0}, +// } +// } +// } +// outputs: a filterset that matches an item if it is in all input filtersets. +// This does NOT deduplicate any items, eg. for the given inputs, the result would be as follows. +// Note that en_materialize() MAY deduplicate, but there is no guarantee it will. (it currently +// doesn't, because an acyclic graph is required for evauator correctness, this might change). +// { type: "filterset", +// root: 4, +// items: { +// { type = "prim_list", value = {1,2,3}}, +// { type = "rel", target = "a", relation = "EQ", value = "1", src = 0 }, +// { type: "prim_list", value = {1,2,3}}, +// { type: "rel", target = "b", relation = "EQ", value = "1", src = 2 }, +// { type: "intersect", srcs = { 1, 3 }} +// } #[doc = include_str!("../api-docs/en_filterset_intersect.md")] pub fn en_filterset_intersect(lua: &Lua, filters: Table) -> mlua::Result
{ let fs = lua.create_table()?; @@ -517,6 +606,37 @@ pub fn en_filterset_intersect(lua: &Lua, filters: Table) -> mlua::Result
Ok(fs) } +// en_filterset_dnf() +// input: +// filters: a list of list of filter descriptions, which is interpreted as a DNF clause list. +// (this example would be (a=1 AND c=0) OR (b=1) +// { +// { +// { target = "a", relation = "EQ", value = "1", src = 0 }, +// { target = "c", relation = "EQ", value = "0", src = 0 }, +// } +// { +// { target = "b", relation = "EQ", value = "1", src = 0}, +// } +// } +// source: a filterset +// outputs: a filterset that matches an item if satisfies either of the AND clauses +// { type: "filterset", +// root: 1, +// items: { +// { type = "prim_list", value = {1,2,3}}, +// { type = "rel_dnf", src = 0, +// clauses = { +// { +// { target = "a", relation = "EQ", value = "1", src = 0 }, +// { target = "c", relation = "EQ", value = "0", src = 0 }, +// } +// { +// { target = "b", relation = "EQ", value = "1", src = 0}, +// } +// } +// } +// } #[doc = include_str!("../api-docs/en_filterset_dnf.md")] pub fn en_filterset_dnf(lua: &Lua, (clauses, src): (Table, Table)) -> mlua::Result
{ let new_fs = deepcopy_table(lua, src)?; @@ -532,6 +652,9 @@ pub fn en_filterset_dnf(lua: &Lua, (clauses, src): (Table, Table)) -> mlua::Resu Ok(new_fs) } +// en_filterset_not() +// input: filterset +// outputs: a filterset that matches an item exactly if it is not in the filterset. #[doc = include_str!("../api-docs/en_filterset_not.md")] pub fn en_filterset_not(lua: &Lua, filterset: Table) -> mlua::Result
{ let new_fs = deepcopy_table(lua, filterset)?;