#radix-tree #http-request #tree #path #router #path-segment #radix

path-tree

path-tree是一个轻量级高性能的Rust HTTP请求路由器

39次发布

0.8.1 2024年6月24日
0.7.7 2024年5月12日
0.7.6 2024年3月24日
0.7.3 2023年12月28日
0.1.4 2019年3月17日

#16 in HTTP服务器

Download history 453/week @ 2024-05-04 709/week @ 2024-05-11 537/week @ 2024-05-18 706/week @ 2024-05-25 681/week @ 2024-06-01 1007/week @ 2024-06-08 1070/week @ 2024-06-15 1248/week @ 2024-06-22 760/week @ 2024-06-29 1011/week @ 2024-07-06 800/week @ 2024-07-13 750/week @ 2024-07-20 1405/week @ 2024-07-27 1177/week @ 2024-08-03 1391/week @ 2024-08-10 1528/week @ 2024-08-17

5,633 每月下载量
29 个Crates中使用了 (直接使用18个)

MIT/Apache

47KB
789

path-tree

A lightweight high performance HTTP request router for Rust

参数语法

模式 类型 描述
:name Normal 匹配路径片段,排除 /
:name? Optional 匹配可选路径片段,排除 /
/:name?/ /:name? OptionalSegment 匹配可选路径片段,排除 /,前缀或后缀应为 /
+ :name+ OneOrMore 匹配路径片段,包括 /
* :name* ZeroOrMore 匹配可选路径片段,包括 /
/*/ /* /:name*/ /:name* ZeroOrMoreSegment 匹配零个或多个路径片段,前缀或后缀应为 /

支持

Case 参数
:a:b a b
:a:b? a b
:a-:b :a.:b :a~:b a b
:a_a-:b_b a_a b_b
:a\\: :a\\_ a
:a\\::b :a\\_:b a b
:a* a
* *1
*.* *1 *2
:a+ a
+ +1
+.+ +1 +2
/*/abc/+/def/g *1 +2

示例

use path_tree::PathTree;

/*
/ •0
├── api/
│   └── + •13
├── login •1
├── public/
│   └── ** •7
├── s
│   ├── ettings •3
│   │   └── /
│   │       └── : •4
│   └── ignup •2
└── : •5
    └── /
        └── : •6
            └── /
                ├── actions/
                │   └── :
                │       └── \:
                │           └── : •10
                ├── releases/download/
                │   └── :
                │       └── /
                │           └── :
                │               └── .
                │                   └── : •8
                ├── tags/
                │   └── :
                │       └── -
                │           └── :
                │               └── -
                │                   └── : •9
                ├── : •11
                └── ** •12
*/
let mut tree = PathTree::new();

tree.insert("/", 0);
tree.insert("/login", 1);
tree.insert("/signup", 2);
tree.insert("/settings", 3);
tree.insert("/settings/:page", 4);
tree.insert("/:user", 5);
tree.insert("/:user/:repo", 6);
tree.insert("/public/:any*", 7);
tree.insert("/:org/:repo/releases/download/:tag/:filename.:ext", 8);
tree.insert("/:org/:repo/tags/:day-:month-:year", 9);
tree.insert("/:org/:repo/actions/:name\\::verb", 10);
tree.insert("/:org/:repo/:page", 11);
tree.insert("/:org/:repo/*", 12);
tree.insert("/api/+", 13);

let (h, p) = tree.find("/").unwrap();
assert_eq!(h, &0);
assert_eq!(p.params(), vec![]);

let (h, p) = tree.find("/login").unwrap();
assert_eq!(h, &1);
assert_eq!(p.params(), vec![]);

let (h, p) = tree.find("/settings/admin").unwrap();
assert_eq!(h, &4);
assert_eq!(p.params(), vec![("page", "admin")]);

let (h, p) = tree.find("/viz-rs").unwrap();
assert_eq!(h, &5);
assert_eq!(p.params(), vec![("user", "viz-rs")]);

let (h, p) = tree.find("/viz-rs/path-tree").unwrap();
assert_eq!(h, &6);
assert_eq!(p.params(), vec![("user", "viz-rs"), ("repo", "path-tree")]);

let (h, p) = tree.find("/rust-lang/rust-analyzer/releases/download/2022-09-12/rust-analyzer-aarch64-apple-darwin.gz").unwrap();
assert_eq!(h, &8);
assert_eq!(
    p.params(),
    vec![
        ("org", "rust-lang"),
        ("repo", "rust-analyzer"),
        ("tag", "2022-09-12"),
        ("filename", "rust-analyzer-aarch64-apple-darwin"),
        ("ext", "gz")
    ]
);

let (h, p) = tree.find("/rust-lang/rust-analyzer/tags/2022-09-12").unwrap();
assert_eq!(h, &9);
assert_eq!(
    p.params(),
    vec![
        ("org", "rust-lang"),
        ("repo", "rust-analyzer"),
        ("day", "2022"),
        ("month", "09"),
        ("year", "12")
    ]
);

let (h, p) = tree.find("/rust-lang/rust-analyzer/actions/ci:bench").unwrap();
assert_eq!(h, &10);
assert_eq!(
    p.params(),
    vec![
        ("org", "rust-lang"),
        ("repo", "rust-analyzer"),
        ("name", "ci"),
        ("verb", "bench"),
    ]
);

let (h, p) = tree.find("/rust-lang/rust-analyzer/stargazers").unwrap();
assert_eq!(h, &11);
assert_eq!(p.params(), vec![("org", "rust-lang"), ("repo", "rust-analyzer"), ("page", "stargazers")]);

let (h, p) = tree.find("/rust-lang/rust-analyzer/stargazers/404").unwrap();
assert_eq!(h, &12);
assert_eq!(p.params(), vec![("org", "rust-lang"), ("repo", "rust-analyzer"), ("*1", "stargazers/404")]);

let (h, p) = tree.find("/public/js/main.js").unwrap();
assert_eq!(h, &7);
assert_eq!(p.params(), vec![("any", "js/main.js")]);

let (h, p) = tree.find("/api/v1").unwrap();
assert_eq!(h, &13);
assert_eq!(p.params(), vec![("+1", "v1")]);

Hyper hello 示例可以在这里找到。

基准测试

$ cargo bench

致谢

它受到以下启发:

其他语言

path-tree 在其他语言的包装器

许可证

根据您的选择,受Apache License, Version 2.0MIT 许可证的许可。
除非您明确声明,否则您提交给此crate的任何贡献,根据Apache-2.0许可证的定义,均应按照上述方式双重许可,不附加任何额外条款或条件。

依赖

~74KB