{"id":20888022,"url":"https://github.com/canop/bet","last_synced_at":"2025-05-12T20:30:47.367Z","repository":{"id":57506153,"uuid":"272228879","full_name":"Canop/bet","owner":"Canop","description":"Build and evaluate binary expression trees","archived":false,"fork":false,"pushed_at":"2024-09-07T08:38:32.000Z","size":58,"stargazers_count":36,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-29T15:06:08.604Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Canop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-14T15:24:37.000Z","updated_at":"2025-04-13T21:04:24.000Z","dependencies_parsed_at":"2024-09-06T19:48:31.863Z","dependency_job_id":"995b9ad3-9ca2-4a9f-a1eb-398c98c2498f","html_url":"https://github.com/Canop/bet","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"c4d3255fe9c061b3f74bf55c93bf93ab16a5da6c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Canop%2Fbet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Canop%2Fbet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Canop%2Fbet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Canop%2Fbet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Canop","download_url":"https://codeload.github.com/Canop/bet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253816656,"owners_count":21968861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-18T08:23:49.924Z","updated_at":"2025-05-12T20:30:47.117Z","avatar_url":"https://github.com/Canop.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![MIT][s2]][l2] [![Latest Version][s1]][l1] [![docs][s3]][l3] [![Chat on Miaou][s4]][l4]\n\n[s1]: https://img.shields.io/crates/v/bet.svg\n[l1]: https://crates.io/crates/bet\n\n[s2]: https://img.shields.io/badge/license-MIT-blue.svg\n[l2]: LICENSE\n\n[s3]: https://docs.rs/bet/badge.svg\n[l3]: https://docs.rs/bet/\n\n[s4]: https://miaou.dystroy.org/static/shields/room.svg\n[l4]: https://miaou.dystroy.org/3\n\nA library building and preparing expressions, for example boolean expressions such as `(A | B) \u0026 !(C | D | E)`,  which can be executed on dynamic contents.\n\nAn expression is built by sequentially pushing the parts: parenthesis, operators, atoms (the \"variables\").\nYou do that by calling the `push_operator`, `open_par`, `close_par` and `push_atom` functions, which build the tree for you.\n\nIt can then be evaluated with the `eval` function which takes as parameters\n\n* a function which gives a value to an atom\n* a function which, given an operator and one or two values, gives a new value\n* a function deciding whether to short-circuit\n\nNormal evaluation order is left to right but is modified with parenthesis.\n\n**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.\n\nIf you wonder whether bet could be applied to your problems, don't hesitate to [come and discuss](https://miaou.dystroy.org/3768).\n## Known open-source usages\n\n### dysk\n\n**bet** is used in [dysk](https://dystroy.org/dysk) to filter filesystems.\n\nExample: `dysk -f '(type=xfs \u0026 remote=no) | size \u003e 5T'`.\n\nHere, the atoms are `type=xfs`, `remote=no`, and `size \u003e 5T`.\n\nTo 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.\n\nHere's how it's done:\n\n```rust\nimpl FromStr for Filter {\n    type Err = ParseExprError;\n    fn from_str(input: \u0026str) -\u003e Result\u003cSelf, ParseExprError\u003e {\n\n        // we start by reading the global structure\n        let mut expr: BeTree\u003cBoolOperator, String\u003e = BeTree::new();\n        for c in input.chars() {\n            match c {\n                '\u0026' =\u003e expr.push_operator(BoolOperator::And),\n                '|' =\u003e expr.push_operator(BoolOperator::Or),\n                '!' =\u003e expr.push_operator(BoolOperator::Not),\n                ' ' =\u003e {},\n                '(' =\u003e expr.open_par(),\n                ')' =\u003e expr.close_par(),\n                _ =\u003e expr.mutate_or_create_atom(String::new).push(c),\n            }\n        }\n\n        // then we parse each leaf\n        let expr = expr.try_map_atoms(|raw| raw.parse())?;\n\n        Ok(Self { expr })\n    }\n}\n```\n\n## broot\n\nIn [broot](https://dystroy.org/broot), **bet** enables composite queries on files.\n\nFor example, `!lock\u0026(carg|c/carg/)` looks for files whose name or content contains \"carg\", but excluding files whose name contains \"lock\".\n\n## rhit\n\n**bet** is used in [rhit](https://dystroy.org/rhit) to filter log lines.\n\nFor example, with `rhit -p 'y \u0026 !( \\d{4} | sp | bl )'`, you get stats on hits on paths containing \"y\" but neither a 4 digits number, \"sp\", nor \"bl\".\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanop%2Fbet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanop%2Fbet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanop%2Fbet/lists"}