use crate::{
collection::{ArrayVectorU8, Vector},
http::server_framework::{Endpoint, RouteMatch},
};
pub trait EndpointNode<CA, E, S, SA>: Endpoint<CA, E, S, SA>
where
E: From<crate::Error>,
{
const IS_ROUTER: bool;
fn paths_indices(
&self,
prev: ArrayVectorU8<RouteMatch, 4>,
vec: &mut Vector<ArrayVectorU8<RouteMatch, 4>>,
) -> crate::Result<()>;
}
impl<CA, E, S, SA, T> EndpointNode<CA, E, S, SA> for &T
where
E: From<crate::Error>,
T: EndpointNode<CA, E, S, SA>,
{
const IS_ROUTER: bool = T::IS_ROUTER;
#[inline]
fn paths_indices(
&self,
prev: ArrayVectorU8<RouteMatch, 4>,
vec: &mut Vector<ArrayVectorU8<RouteMatch, 4>>,
) -> crate::Result<()> {
(*self).paths_indices(prev, vec)
}
}
#[cfg(test)]
mod tests {
use crate::{
collection::{ArrayVectorU8, Vector},
http::{
ManualStream, MsgBufferString, OperationMode, StatusCode,
server_framework::{EndpointNode, RouteMatch, Router, StateClean, get},
},
};
#[test]
fn paths_indices() {
let paths = paths!(
("/a", get(auto)),
("/a", Router::paths(paths!(("/b", get(auto)))).unwrap()),
("/a", Router::paths(paths!(("/c/d", get(auto)))).unwrap()),
(
"/a",
Router::paths(paths!(("/d", Router::paths(paths!(("/e", get(auto)))).unwrap()))).unwrap()
),
("/f/g", get(auto)),
("/f/g", Router::paths(paths!(("/h", get(auto)))).unwrap()),
("/i/j/k", get(manual)),
(
"/l",
Router::paths(paths!(
("/m", get(auto)),
("/n", get(auto)),
("/o", Router::paths(paths!(("/p", get(auto)), ("/q", get(auto)))).unwrap())
))
.unwrap()
),
);
let mut vec = Vector::new();
paths.paths_indices(ArrayVectorU8::new(), &mut vec).unwrap();
assert_eq!(
vec.as_slice(),
&[
ArrayVectorU8::from_copyable_slice(&[RouteMatch::new(
0,
OperationMode::Auto,
"/a".try_into().unwrap()
)])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(1, OperationMode::Auto, "/a".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/b".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(2, OperationMode::Auto, "/a".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/c/d".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(3, OperationMode::Auto, "/a".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/d".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/e".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[RouteMatch::new(
4,
OperationMode::Auto,
"/f/g".try_into().unwrap()
)])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(5, OperationMode::Auto, "/f/g".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/h".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[RouteMatch::new(
6,
OperationMode::Manual,
"/i/j/k".try_into().unwrap()
)])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(7, OperationMode::Auto, "/l".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/m".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(7, OperationMode::Auto, "/l".try_into().unwrap()),
RouteMatch::new(1, OperationMode::Auto, "/n".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(7, OperationMode::Auto, "/l".try_into().unwrap()),
RouteMatch::new(2, OperationMode::Auto, "/o".try_into().unwrap()),
RouteMatch::new(0, OperationMode::Auto, "/p".try_into().unwrap())
])
.unwrap(),
ArrayVectorU8::from_copyable_slice(&[
RouteMatch::new(7, OperationMode::Auto, "/l".try_into().unwrap()),
RouteMatch::new(2, OperationMode::Auto, "/o".try_into().unwrap()),
RouteMatch::new(1, OperationMode::Auto, "/q".try_into().unwrap())
])
.unwrap(),
]
);
}
async fn auto(_: StateClean<'_, (), (), MsgBufferString>) -> crate::Result<StatusCode> {
Ok(StatusCode::Ok)
}
async fn manual(_: ManualStream<(), (), ()>) -> crate::Result<()> {
Ok(())
}
}