Use associated type for resolver state
This commit is contained in:
parent
5e48aa725d
commit
33fd061a8a
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "actix-webfinger"
|
||||
description = "Types and helpers to create and fetch Webfinger resources"
|
||||
version = "0.3.0-alpha.4"
|
||||
version = "0.3.0-alpha.5"
|
||||
license = "GPL-3.0"
|
||||
authors = ["asonix <asonix@asonix.dog>"]
|
||||
repository = "https://git.asonix.dog/Aardwolf/actix-webfinger"
|
||||
|
@ -19,4 +19,5 @@ thiserror = "1.0"
|
|||
actix = "0.10.0-alpha.1"
|
||||
actix-rt = "1.0.0"
|
||||
actix-web = { version = "3.0.0-alpha.1", features = ["openssl"] }
|
||||
pretty_env_logger = "0.4"
|
||||
serde_json = "1.0"
|
||||
|
|
|
@ -15,7 +15,7 @@ First, add Actix Webfinger as a dependency
|
|||
[dependencies]
|
||||
actix = "0.10.0-alpha.1"
|
||||
actix-web = "3.0.0-alpha.1"
|
||||
actix-webfinger = "0.3.0-alpha.4"
|
||||
actix-webfinger = "0.3.0-alpha.5"
|
||||
```
|
||||
|
||||
Then use it in your application
|
||||
|
@ -49,7 +49,8 @@ pub struct MyState {
|
|||
|
||||
pub struct MyResolver;
|
||||
|
||||
impl Resolver<Data<MyState>> for MyResolver {
|
||||
impl Resolver for MyResolver {
|
||||
type State = Data<MyState>;
|
||||
type Error = actix_web::error::JsonPayloadError;
|
||||
|
||||
fn find(
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::error::Error;
|
|||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let client = Client::default();
|
||||
let wf = Webfinger::fetch(&client, "asonix@asonix.dog", "localhost:8000", false).await?;
|
||||
let wf = Webfinger::fetch(&client, "asonix@localhost:8000", "localhost:8000", false).await?;
|
||||
|
||||
println!("asonix's webfinger:\n{:#?}", wf);
|
||||
Ok(())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use actix_web::{web::Data, App, HttpServer};
|
||||
use actix_web::{middleware::Logger, web::Data, App, HttpServer};
|
||||
use actix_webfinger::{Resolver, Webfinger};
|
||||
use std::{error::Error, future::Future, pin::Pin};
|
||||
|
||||
|
@ -9,7 +9,8 @@ pub struct MyState {
|
|||
|
||||
pub struct MyResolver;
|
||||
|
||||
impl Resolver<Data<MyState>> for MyResolver {
|
||||
impl Resolver for MyResolver {
|
||||
type State = Data<MyState>;
|
||||
type Error = actix_web::error::JsonPayloadError;
|
||||
|
||||
fn find(
|
||||
|
@ -29,12 +30,15 @@ impl Resolver<Data<MyState>> for MyResolver {
|
|||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
pretty_env_logger::init();
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.data(MyState {
|
||||
domain: "localhost:8000".to_owned(),
|
||||
})
|
||||
.service(actix_webfinger::resource::<_, MyResolver>())
|
||||
.wrap(Logger::default())
|
||||
.service(actix_webfinger::resource::<MyResolver>())
|
||||
})
|
||||
.bind("127.0.0.1:8000")?
|
||||
.run()
|
||||
|
|
59
src/lib.rs
59
src/lib.rs
|
@ -2,7 +2,7 @@
|
|||
//! A library to aid in resolving and providing webfinger objects with the Actix Web web framework.
|
||||
//!
|
||||
//! The main functionality this crate provides is through the `Webfinger::fetch` method for Actix
|
||||
//! Web-based clients, and the `Resolver<S>` trait for Actix Web-based servers.
|
||||
//! Web-based clients, and the `Resolver` trait for Actix Web-based servers.
|
||||
//!
|
||||
//! ### Usage
|
||||
//! First, add Actix Webfinger as a dependency
|
||||
|
@ -49,7 +49,8 @@
|
|||
//!
|
||||
//! pub struct MyResolver;
|
||||
//!
|
||||
//! impl Resolver<Data<MyState>> for MyResolver {
|
||||
//! impl Resolver for MyResolver {
|
||||
//! type State = Data<MyState>;
|
||||
//! type Error = actix_web::error::JsonPayloadError;
|
||||
//!
|
||||
//! fn find(
|
||||
|
@ -74,7 +75,7 @@
|
|||
//! .data(MyState {
|
||||
//! domain: "asonix.dog".to_owned(),
|
||||
//! })
|
||||
//! .service(actix_webfinger::resource::<_, MyResolver>())
|
||||
//! .service(actix_webfinger::resource::<MyResolver>())
|
||||
//! })
|
||||
//! .bind("127.0.0.1:8000")?
|
||||
//! .run()
|
||||
|
@ -171,19 +172,18 @@ impl Guard for WebfingerGuard {
|
|||
///
|
||||
/// HttpServer::new(|| {
|
||||
/// App::new()
|
||||
/// .service(actix_webfinger::resource::<_, MyResolver>())
|
||||
/// .service(actix_webfinger::resource::<MyResolver>())
|
||||
/// })
|
||||
/// .bind("127.0.0.1:8000")?
|
||||
/// .start();
|
||||
/// ```
|
||||
pub fn resource<S, R>() -> Resource
|
||||
pub fn resource<R>() -> Resource
|
||||
where
|
||||
R: Resolver<S> + 'static,
|
||||
S: FromRequest + 'static,
|
||||
R: Resolver + 'static,
|
||||
{
|
||||
actix_web::web::resource("/.well-known/webfinger")
|
||||
.guard(WebfingerGuard)
|
||||
.route(get().to(R::endpoint))
|
||||
.route(get().to(endpoint::<R>))
|
||||
}
|
||||
|
||||
/// A simple way to mount the webfinger service inside the /.well-known scope
|
||||
|
@ -197,20 +197,19 @@ where
|
|||
/// .data(())
|
||||
/// .service(
|
||||
/// scope("/")
|
||||
/// .service(resource::<(), MyResolver>())
|
||||
/// .service(resource::<MyResolver>())
|
||||
/// )
|
||||
/// })
|
||||
/// .bind("127.0.0.1:8000")
|
||||
/// .start();
|
||||
/// ```
|
||||
pub fn scoped<S, R>() -> Resource
|
||||
pub fn scoped<R>() -> Resource
|
||||
where
|
||||
R: Resolver<S> + 'static,
|
||||
S: FromRequest + 'static,
|
||||
R: Resolver + 'static,
|
||||
{
|
||||
actix_web::web::resource("/webfinger")
|
||||
.guard(WebfingerGuard)
|
||||
.route(get().to(R::endpoint))
|
||||
.route(get().to(endpoint::<R>))
|
||||
}
|
||||
|
||||
/// The error created if the webfinger resource query is malformed
|
||||
|
@ -312,25 +311,20 @@ pub struct WebfingerQuery {
|
|||
|
||||
/// A trait to ease the implementation of Webfinger Resolvers
|
||||
///
|
||||
/// This trait can be implemented, and the provided `endpoint` method used to serve requests to an
|
||||
/// Actix Web server.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use actix_webfinger::{Resolver, Webfinger};
|
||||
/// use std::{future::Future, pin::Pin};
|
||||
///
|
||||
/// struct MyResolver;
|
||||
///
|
||||
/// impl<S> Resolver<S> for MyResolver
|
||||
/// where
|
||||
/// S: FromRequest,
|
||||
/// {
|
||||
/// impl Resolver for MyResolver {
|
||||
/// type State = ();
|
||||
/// type Error = CustomError;
|
||||
///
|
||||
/// fn find(
|
||||
/// account: &str,
|
||||
/// domain: &str,
|
||||
/// _state: S
|
||||
/// _state: Self::State,
|
||||
/// ) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>> {
|
||||
/// let webfinger = Webfinger::new(&format!("{}@{}", account, domain));
|
||||
///
|
||||
|
@ -345,7 +339,7 @@ pub struct WebfingerQuery {
|
|||
/// HttpServer::new(|| {
|
||||
/// App::new()
|
||||
/// .data(())
|
||||
/// .service(resource::<Data<()>, MyResolver>())
|
||||
/// .service(resource::<MyResolver>())
|
||||
/// })
|
||||
/// .bind("127.0.0.1:8000")?
|
||||
/// .run()
|
||||
|
@ -354,30 +348,31 @@ pub struct WebfingerQuery {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Resolver<S>
|
||||
where
|
||||
S: FromRequest + 'static,
|
||||
{
|
||||
pub trait Resolver {
|
||||
type State: FromRequest + 'static;
|
||||
type Error: ResponseError + 'static;
|
||||
|
||||
fn find(
|
||||
account: &str,
|
||||
domain: &str,
|
||||
state: S,
|
||||
state: Self::State,
|
||||
) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>>;
|
||||
}
|
||||
|
||||
fn endpoint(
|
||||
(query, state): (Query<WebfingerQuery>, S),
|
||||
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>>>> {
|
||||
pub fn endpoint<R>(
|
||||
(query, state): (Query<WebfingerQuery>, R::State),
|
||||
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, R::Error>>>>
|
||||
where
|
||||
R: Resolver,
|
||||
{
|
||||
let WebfingerResource { account, domain } = query.into_inner().resource;
|
||||
|
||||
Box::pin(async move {
|
||||
match Self::find(&account, &domain, state).await? {
|
||||
match R::find(&account, &domain, state).await? {
|
||||
Some(w) => Ok(w.respond()),
|
||||
None => Ok(HttpResponse::NotFound().finish()),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The webfinger Link type
|
||||
|
|
Loading…
Reference in a new issue