Expand description
§About
This crate allows boolean expressions of tags to be written, parsed, and evaluated (e.g. converted to SQL for selecting out of a database). The tags can be restricted to the more typical single-value kind, but support is also supplied for key-value tags - this is achieved by making the tag name optional.
For example, to get all British and American scientists who are not chemists (see below for a proper example in Rust) one could use:
((nationality=american & scientist) | (=british & scientist)) & !chemist & person
The input requirements aren’t rigid and so to get the same result we could also write, say:
(nationality=american | =british) & scientist & !chemist & person
Where:
nationality=americanmeans entities with the a tag whose name isnationalityand whose value isamerican=britishis the same asbritishand means entities with a tag value ofbritish!chemistmeans entities that do not have the tag valuechemistpersonmeans those entities that have a tag value ofperson
§Syntax
&forAND(&&is a lexical error)|forOR(||is a lexical error)(and)for logical grouping ()(is a syntax error)!forNOTtag-name=tag-value,=tag-value, andtag-valueare all valid tags
§Parsing
A valid boolean expression must contain at least 1 tag.
This modules provides functionality for both:
- String (or custom type with necessary trait) → Bool expression tree
- String (or custom type with necessary trait) → Lexical token stream → Bool expression tree
See below for examples and clarification.
§Examples
§Basic
The simplest way to use this crate is to parse some boolean tag expression string and to then select items out of a database. Here is how to do that:
use bool_tag_expr::BoolTagExpr;
use bool_tag_expr::DbTableInfo;
// The boolean tag expression
let expr_str = "(nationality=american | =british) & scientist & !chemist & person";
// Parse it, returning early if there is an error
let expr_tree = BoolTagExpr::from(expr_str)?;
// Setup the database info
let table_name = "entity_tags";
let id_column = "entity_id";
let tag_name_column = "name";
let tag_value_column = "value";
let table_info = DbTableInfo::from(table_name, id_column, tag_name_column, tag_value_column)?;
// Generate the SQL using the expression tree and the database info
let bool_expr_sql_str = expr_tree.to_sql(&table_info);
// Create the full SQL statement
let sql = format!(
r#"
SELECT DISTINCT {id_column}
FROM ({bool_expr_sql_str})
LIMIT ?
"#
);
§Advanced
Should you want to get a BoolTagExpr from some type that isn’t readily
converted into a string, you can implement BoolTagExprLexicalParse for
it. You will then automatically get an implementation of
BoolTagExprSyntaxParse. You can then use BoolTagExpr::from(my_var)?;
as above. Alternatively, you can lexically parse and then syntactically
parse any type implementing these 2 traits (already implemented for
strings). This might be helpful if, for example, you want to limit the
number of tags in a boolean expression:
use bool_tag_expr::BoolTagExprSyntaxParse;
use bool_tag_expr::BoolTagExprLexicalParse;
use bool_tag_expr::Token;
// Get the boolean expression (e.g. from user input)
let expr = "(german | british) & poet";
// Parse (lexical only) the boolean expression
let tokens = expr.lexical_parse().unwrap_or_else(|error| {
eprintln!("Lexical parse error: {error}");
std::process::exit(1);
});
// Count the number of tags
let tag_count = tokens
.tokens()
.iter()
.filter(|token| if let Token::Tag(_) = token { true } else { false })
.count();
// Panic if there are too many tags
if tag_count > 5 {
panic!()
}
// Parse (syntax) the tokens
let expr_tree = expr.syntax_parse().unwrap_or_else(|error| {
eprintln!("Syntax parse error: {error}");
std::process::exit(1);
});
§Crate Features
There is only 1 optional feature: sqlx. It is not selected by default.
Unless you are planning on compiling parts of the crate to WASM, it is
recommended that you use the sqlx feature. If you are planning on pulling
data out of a database, you must use this feature.
§Warnings
For the NOT functionality to work correctly for all entires, every entry
must have at least 1 tag.
Structs§
- Bool
TagExpr - A boolean expression tree.
- DbTable
Info - Holds information about the table against which the SQL will be run - this is used to produce the SQL.
- Lexical
Token Stream - A stream of lexical
Tokens - Tag
- A
Tagmay optionally have a name, but must have a value - TagComponent
- Represents both tag names and values (see
TagName&TagValue).
Enums§
- Lexical
Parse Error - Possible lexical errors
- Node
- Possible elements of a boolean expression (a boolean expression tree is made up of these)
- Parse
Error - All possible lexical and syntactic parsing errors
- SqlTable
Info Error - Error that arises when attempting to use an invalid SQL identifier
- Syntax
Parse Error - Possible syntax errors
- TagError
- Errors that can arise in relation to a
Tag - Token
- Possible lexical tokens
Traits§
- Bool
TagExpr Lexical Parse - Implementing types can be lexically parsed to a token stream
- Bool
TagExpr Syntax Parse - Implementing types can be (lexically and) syntactically parsed to a boolean expression tree
Type Aliases§
- TagName
- An alias of
TagComponent - TagValue
- An alias of
TagComponent - Tags
- An alias of
BTreeSet<Tag>