MCPcopy Index your code
hub / github.com/Canop/bet

github.com/Canop/bet @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
60 symbols 119 edges 6 files 22 documented · 37%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

MIT Latest Version docs Chat on Miaou

A library building and preparing expressions, for example boolean expressions such as (A | B) & !(C | D | E), which can be executed on dynamic contents.

An expression is built by sequentially pushing the parts: parenthesis, operators, atoms (the "variables"). You do that by calling the push_operator, open_par, close_par and push_atom functions, which build the tree for you.

It can then be evaluated with the eval function which takes as parameters

  • a function which gives a value to an atom
  • a function which, given an operator and one or two values, gives a new value
  • a function deciding whether to short-circuit

Normal evaluation order is left to right but is modified with parenthesis.

bet is designed around separation of building, transformations, and evaluation, so that an expression can be efficiently applied on many inputs. bet is designed for very fast evaluation.

If you wonder whether bet could be applied to your problems, don't hesitate to come and discuss.

Known open-source usages

dysk

bet is used in dysk to filter filesystems.

Example: dysk -f '(type=xfs & remote=no) | size > 5T'.

Here, the atoms are type=xfs, remote=no, and size > 5T.

To parse such expression, the simplest solution is to first parse it with atoms being simple strings, then apply try_map_atoms on the tree to replace the strings with structs which can be efficiently evaluated on many entries.

Here's how it's done:

impl FromStr for Filter {
    type Err = ParseExprError;
    fn from_str(input: &str) -> Result<Self, ParseExprError> {

        // we start by reading the global structure
        let mut expr: BeTree<BoolOperator, String> = BeTree::new();
        for c in input.chars() {
            match c {
                '&' => expr.push_operator(BoolOperator::And),
                '|' => expr.push_operator(BoolOperator::Or),
                '!' => expr.push_operator(BoolOperator::Not),
                ' ' => {},
                '(' => expr.open_par(),
                ')' => expr.close_par(),
                _ => expr.mutate_or_create_atom(String::new).push(c),
            }
        }

        // then we parse each leaf
        let expr = expr.try_map_atoms(|raw| raw.parse())?;

        Ok(Self { expr })
    }
}

broot

In broot, bet enables composite queries on files.

For example, !lock&(carg|c/carg/) looks for files whose name or content contains "carg", but excluding files whose name contains "lock".

rhit

bet is used in rhit to filter log lines.

For example, with rhit -p 'y & !( \d{4} | sp | bl )', you get stats on hits on paths containing "y" but neither a 4 digits number, "sp", nor "bl".

Core symbols most depended-on inside this repo

push_operator
called by 7
src/be_tree.rs
push_atom
called by 4
src/be_tree.rs
store_node
called by 3
src/be_tree.rs
push
called by 3
src/be_tree.rs
open_par
called by 3
src/be_tree.rs
close_par
called by 3
src/be_tree.rs
is_none
called by 3
src/child.rs
is_some
called by 3
src/child.rs

Shape

Method 48
Enum 5
Function 5
Class 2

Languages

Rust100%

Modules by API surface

src/be_tree.rs43 symbols
src/test_bool.rs6 symbols
src/test_bool_faillible.rs5 symbols
src/node.rs3 symbols
src/child.rs3 symbols

For agents

$ claude mcp add bet \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact