Skip to content

Commit 26367b9

Browse files
authored
axum: use Vec for PathRouter (#3509)
1 parent 5090160 commit 26367b9

File tree

2 files changed

+31
-55
lines changed

2 files changed

+31
-55
lines changed

axum/src/routing/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ macro_rules! panic_on_err {
5858
}
5959

6060
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
61-
pub(crate) struct RouteId(u32);
61+
pub(crate) struct RouteId(usize);
6262

6363
/// The router type for composing handlers and services.
6464
///

axum/src/routing/path_router.rs

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ use super::{
1414
};
1515

1616
pub(super) struct PathRouter<S> {
17-
routes: HashMap<RouteId, Endpoint<S>>,
17+
routes: Vec<Endpoint<S>>,
1818
node: Arc<Node>,
19-
prev_route_id: RouteId,
2019
v7_checks: bool,
2120
}
2221

@@ -71,11 +70,11 @@ where
7170
) -> Result<(), Cow<'static, str>> {
7271
validate_path(self.v7_checks, path)?;
7372

74-
let endpoint = if let Some((route_id, Endpoint::MethodRouter(prev_method_router))) = self
73+
if let Some((route_id, Endpoint::MethodRouter(prev_method_router))) = self
7574
.node
7675
.path_to_route_id
7776
.get(path)
78-
.and_then(|route_id| self.routes.get(route_id).map(|svc| (*route_id, svc)))
77+
.and_then(|route_id| self.routes.get(route_id.0).map(|svc| (*route_id, svc)))
7978
{
8079
// if we're adding a new `MethodRouter` to a route that already has one just
8180
// merge them. This makes `.route("/", get(_)).route("/", post(_))` work
@@ -84,15 +83,11 @@ where
8483
.clone()
8584
.merge_for_path(Some(path), method_router)?,
8685
);
87-
self.routes.insert(route_id, service);
88-
return Ok(());
86+
self.routes[route_id.0] = service;
8987
} else {
90-
Endpoint::MethodRouter(method_router)
91-
};
92-
93-
let id = self.next_route_id();
94-
self.set_node(path, id)?;
95-
self.routes.insert(id, endpoint);
88+
let endpoint = Endpoint::MethodRouter(method_router);
89+
self.new_route(path, endpoint)?;
90+
}
9691

9792
Ok(())
9893
}
@@ -102,7 +97,7 @@ where
10297
H: Handler<T, S>,
10398
T: 'static,
10499
{
105-
for (_, endpoint) in self.routes.iter_mut() {
100+
for endpoint in self.routes.iter_mut() {
106101
if let Endpoint::MethodRouter(rt) = endpoint {
107102
*rt = rt.clone().default_fallback(handler.clone());
108103
}
@@ -129,9 +124,7 @@ where
129124
) -> Result<(), Cow<'static, str>> {
130125
validate_path(self.v7_checks, path)?;
131126

132-
let id = self.next_route_id();
133-
self.set_node(path, id)?;
134-
self.routes.insert(id, endpoint);
127+
self.new_route(path, endpoint)?;
135128

136129
Ok(())
137130
}
@@ -143,21 +136,28 @@ where
143136
.map_err(|err| format!("Invalid route {path:?}: {err}"))
144137
}
145138

139+
fn new_route(&mut self, path: &str, endpoint: Endpoint<S>) -> Result<(), String> {
140+
let id = RouteId(self.routes.len());
141+
self.set_node(path, id)?;
142+
self.routes.push(endpoint);
143+
Ok(())
144+
}
145+
146146
pub(super) fn merge(&mut self, other: Self) -> Result<(), Cow<'static, str>> {
147147
let Self {
148148
routes,
149149
node,
150-
prev_route_id: _,
151150
v7_checks,
152151
} = other;
153152

154153
// If either of the two did not allow paths starting with `:` or `*`, do not allow them for the merged router either.
155154
self.v7_checks |= v7_checks;
156155

157-
for (id, route) in routes {
156+
for (id, route) in routes.into_iter().enumerate() {
157+
let route_id = RouteId(id);
158158
let path = node
159159
.route_id_to_path
160-
.get(&id)
160+
.get(&route_id)
161161
.expect("no path for route id. This is a bug in axum. Please file an issue");
162162

163163
match route {
@@ -179,15 +179,15 @@ where
179179
let Self {
180180
routes,
181181
node,
182-
prev_route_id: _,
183182
// Ignore the configuration of the nested router
184183
v7_checks: _,
185184
} = router;
186185

187-
for (id, endpoint) in routes {
186+
for (id, endpoint) in routes.into_iter().enumerate() {
187+
let route_id = RouteId(id);
188188
let inner_path = node
189189
.route_id_to_path
190-
.get(&id)
190+
.get(&route_id)
191191
.expect("no path for route id. This is a bug in axum. Please file an issue");
192192

193193
let path = path_for_nested_route(prefix, inner_path);
@@ -259,16 +259,12 @@ where
259259
let routes = self
260260
.routes
261261
.into_iter()
262-
.map(|(id, endpoint)| {
263-
let route = endpoint.layer(layer.clone());
264-
(id, route)
265-
})
262+
.map(|endpoint| endpoint.layer(layer.clone()))
266263
.collect();
267264

268265
Self {
269266
routes,
270267
node: self.node,
271-
prev_route_id: self.prev_route_id,
272268
v7_checks: self.v7_checks,
273269
}
274270
}
@@ -292,16 +288,12 @@ where
292288
let routes = self
293289
.routes
294290
.into_iter()
295-
.map(|(id, endpoint)| {
296-
let route = endpoint.layer(layer.clone());
297-
(id, route)
298-
})
291+
.map(|endpoint| endpoint.layer(layer.clone()))
299292
.collect();
300293

301294
Self {
302295
routes,
303296
node: self.node,
304-
prev_route_id: self.prev_route_id,
305297
v7_checks: self.v7_checks,
306298
}
307299
}
@@ -314,21 +306,17 @@ where
314306
let routes = self
315307
.routes
316308
.into_iter()
317-
.map(|(id, endpoint)| {
318-
let endpoint: Endpoint<S2> = match endpoint {
319-
Endpoint::MethodRouter(method_router) => {
320-
Endpoint::MethodRouter(method_router.with_state(state.clone()))
321-
}
322-
Endpoint::Route(route) => Endpoint::Route(route),
323-
};
324-
(id, endpoint)
309+
.map(|endpoint| match endpoint {
310+
Endpoint::MethodRouter(method_router) => {
311+
Endpoint::MethodRouter(method_router.with_state(state.clone()))
312+
}
313+
Endpoint::Route(route) => Endpoint::Route(route),
325314
})
326315
.collect();
327316

328317
PathRouter {
329318
routes,
330319
node: self.node,
331-
prev_route_id: self.prev_route_id,
332320
v7_checks: self.v7_checks,
333321
}
334322
}
@@ -366,7 +354,7 @@ where
366354

367355
let endpoint = self
368356
.routes
369-
.get(&id)
357+
.get(id.0)
370358
.expect("no route for id. This is a bug in axum. Please file an issue");
371359

372360
let req = Request::from_parts(parts, body);
@@ -382,24 +370,13 @@ where
382370
Err(MatchError::NotFound) => Err((Request::from_parts(parts, body), state)),
383371
}
384372
}
385-
386-
fn next_route_id(&mut self) -> RouteId {
387-
let next_id = self
388-
.prev_route_id
389-
.0
390-
.checked_add(1)
391-
.expect("Over `u32::MAX` routes created. If you need this, please file an issue.");
392-
self.prev_route_id = RouteId(next_id);
393-
self.prev_route_id
394-
}
395373
}
396374

397375
impl<S> Default for PathRouter<S> {
398376
fn default() -> Self {
399377
Self {
400378
routes: Default::default(),
401379
node: Default::default(),
402-
prev_route_id: RouteId(0),
403380
v7_checks: true,
404381
}
405382
}
@@ -419,7 +396,6 @@ impl<S> Clone for PathRouter<S> {
419396
Self {
420397
routes: self.routes.clone(),
421398
node: self.node.clone(),
422-
prev_route_id: self.prev_route_id,
423399
v7_checks: self.v7_checks,
424400
}
425401
}

0 commit comments

Comments
 (0)