Skip to content

Instantly share code, notes, and snippets.

@Nemo157
Last active November 3, 2018 12:36
Show Gist options
  • Save Nemo157/403bdd829eef569779fda50bb3732ccb to your computer and use it in GitHub Desktop.
Save Nemo157/403bdd829eef569779fda50bb3732ccb to your computer and use it in GitHub Desktop.
trait App<Input>
where
Input: { request: http::Request }
{
type Output: Into<http::Response>;
fn call(self, input: Input) -> Self::Output;
}
struct AuthApp<T> {
next: T,
}
impl<T, Input> App<Input> for AuthApp<T>
where
Input: { request: http::Request },
T: App<{ user: Result<User, AuthError>, ..Input }>
{
type Output = T::Output;
fn call(self, input: Input) -> Self::Output {
let user = authenticate(&input.request);
self.next({ user, ..input })
}
}
struct User { /* … */ }
enum AuthError { /* … */ }
fn authenticate(_: &http::Request) -> Result<User, AuthError> { /* … */ }
trait HasField<const Name: &'static str> {
type Type;
fn get_ref(&self) -> &Self::Type;
}
trait AddField<const Name: &'static str, Type> {
type Output;
fn add(self, value: Type) -> Self::Output;
}
trait App<Input>
where
Input: HasField<"request", Type = http::Request>
{
type Output: Into<http::Response>;
fn call(self, input: Input) -> Self::Output;
}
struct AuthApp<T> {
next: T,
}
impl<T, Input> App<Input> for AuthApp<T>
where
Input: HasField<"request", Type = http::Request> + AddField<"user", Result<User, AuthError>>,
T: App<<Input as AddField<"user", Result<User, AuthError>>>::Output>
{
type Output = T::Output;
fn call(self, input: Input) -> Self::Output {
let user = authenticate(input.get_ref());
self.next(input.add(user))
}
}
struct User { /* … */ }
enum AuthError { /* … */ }
fn authenticate(_: &http::Request) -> Result<User, AuthError> { /* … */ }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment