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服务器
5,633 每月下载量
在 29 个Crates中使用了 (直接使用18个)
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
致谢
它受到以下启发:
- rax
- httprouter
- echo 路由器
- path-to-regexp
- gofiber 路由器
- trekjs 路由器
其他语言
path-tree 在其他语言的包装器
许可证
根据您的选择,受Apache License, Version 2.0 或 MIT 许可证的许可。除非您明确声明,否则您提交给此crate的任何贡献,根据Apache-2.0许可证的定义,均应按照上述方式双重许可,不附加任何额外条款或条件。
依赖
~74KB