//! Extractors for request data.
//!
//! Implements [`FromRequest`] for [`Params`] and [`Cookies`]. Both of these are infallible
//! conversions, simply wrapping the underlying [`Request`] methods.

use crate::http::{FromRequest, Request, cookies::Cookies, params::Params};
use std::convert::Infallible;

impl<'buf, State> FromRequest<'_, 'buf, '_, State> for Params<'buf> {
	type Error = Infallible;

	async fn from_request(req: Request<'_, 'buf>, _state: &State) -> Result<Self, Self::Error> {
		Ok(req.params())
	}
}

impl<'buf, State> FromRequest<'_, 'buf, '_, State> for Cookies<'buf> {
	type Error = Infallible;

	async fn from_request(req: Request<'_, 'buf>, _state: &State) -> Result<Self, Self::Error> {
		Ok(req.cookies())
	}
}

#[cfg(test)]
mod tests {
	use super::*;
	use crate::Header;

	#[test]
	fn test_params_from_request() {
		let request = Request::new("GET", "/test?foo=bar&baz=qux", &[], &[]);
		let params = futures_lite::future::block_on(Params::from_request(request, &())).unwrap();
		assert_eq!(
			params.find("foo").next(),
			Some(std::borrow::Cow::Borrowed("bar"))
		);
		assert_eq!(
			params.find("baz").next(),
			Some(std::borrow::Cow::Borrowed("qux"))
		);
	}

	#[test]
	fn test_cookies_from_request() {
		let headers = [Header {
			name: "Cookie",
			value: b"foo=bar; baz=qux",
		}];
		let request = Request::new("GET", "/test", &headers, &[]);
		let cookies = futures_lite::future::block_on(Cookies::from_request(request, &())).unwrap();
		assert_eq!(cookies.find("foo"), Some(b"bar".as_slice()));
		assert_eq!(cookies.find("baz"), Some(b"qux".as_slice()));
	}
}
