diff --git a/src/route.rs b/src/route.rs index b9273114..6593d002 100644 --- a/src/route.rs +++ b/src/route.rs @@ -1,15 +1,18 @@ use crate::{ healthcheck::HealthCheck, - request::{RequestParam, RequestParams}, + request::{RequestParam, RequestParamType, RequestParams}, }; use async_trait::async_trait; use derive_more::From; use futures::future::{BoxFuture, Future, FutureExt}; use serde::Serialize; use snafu::{OptionExt, Snafu}; +use std::collections::HashMap; use std::convert::Infallible; use std::fmt::{self, Display, Formatter}; use std::marker::PhantomData; +use std::pin::Pin; +use std::str::FromStr; use tide::{ http::{ self, @@ -19,7 +22,6 @@ use tide::{ }, Body, }; -use tracing::info; /// An error returned by a route handler. /// @@ -163,6 +165,10 @@ pub struct Route { #[derive(Clone, Debug, Snafu)] pub enum RouteParseError { + MissingPathArray, + PathElementError, + InvalidTypeExpression, + UnrecognizedType, MethodMustBeString, InvalidMethod, MissingPath, @@ -174,9 +180,41 @@ pub enum RouteParseError { impl Route { /// Parse a [Route] from a TOML specification. pub fn new(name: String, spec: &toml::Value) -> Result { - // TODO this should be try_into... - info!("name: {}", name); - info!("spec: {:?}", spec); + let paths: Vec = spec["PATH"] + .as_array() + .ok_or(RouteParseError::MissingPathArray)? + .iter() + .map(|v| { + v.as_str() + .ok_or(RouteParseError::PathElementError) + .unwrap() + .to_string() + }) + .collect(); + let mut pmap = HashMap::::new(); + for path in paths.iter() { + for seg in path.split('/') { + if seg.starts_with(':') { + let ptype = RequestParamType::from_str( + spec[seg] + .as_str() + .ok_or(RouteParseError::InvalidTypeExpression)?, + ) + .map_err(|_| RouteParseError::UnrecognizedType)?; + // TODO Should the map key and name be different? If + // not, then RequestParam::name is redundant. + pmap.insert( + seg.to_string(), + RequestParam { + name: seg.to_string(), + param_type: ptype, + // TODO How should we encode optioanl params? + required: true, + }, + ); + } + } + } Ok(Route { name, patterns: match spec.get("PATH").context(MissingPathSnafu)? { @@ -215,7 +253,7 @@ impl Route { .context(MethodMustBeStringSnafu)? .parse() .map_err(|_| RouteParseError::InvalidMethod)?, - None => Method::Get, + None => http::Method::Get, }, doc: String::new(), handler: None,