Generic ParameterInput, createAccount xrpc parsing

This commit is contained in:
Julia Lange 2025-07-15 10:35:27 -07:00
parent 031faf7db1
commit 6d45fb2f70
Signed by: Julia
SSH key fingerprint: SHA256:5DJcfxa5/fKCYn57dcabJa2vN2e6eT0pBerYi5SUbto
2 changed files with 58 additions and 34 deletions

View file

@ -1,15 +1,28 @@
use router::{
Router,
Endpoint,
xrpc::{
QueryInput,
XrpcEndpoint,
ProcedureInput,
Response,
error,
},
};
use serde::Deserialize;
use atproto::types::Nsid;
use http::status::StatusCode;
use tracing::{
event,
instrument,
Level,
};
use std::fmt::Debug;
struct Config {
entryway_url: String,
entryway_did: String,
entryway_plc_rotation_key: String,
entryway_jwt_key_256_hex: String,
}
#[tokio::main]
async fn main() {
@ -17,17 +30,27 @@ async fn main() {
let _ = tracing::subscriber::set_global_default(subscriber);
let mut router = Router::new();
// let get_nsid = Nsid::new(String::from("me.woach.get")).expect("me.woach.get is a valid nsid");
// let post_nsid = Nsid::new(String::from("me.woach.post")).expect("me.woach.post is a valid nsid");
// router = router.add_endpoint(Endpoint::new_xrpc_query(get_nsid, test));
// router = router.add_endpoint(Endpoint::new_xrpc_procedure(post_nsid, test2));
let create_account_nsid: Nsid = "com.atproto.server.createAccount".parse::<Nsid>().expect("valid nsid");
router = router.add_endpoint(XrpcEndpoint::new_procedure(create_account_nsid, create_account));
router.serve().await;
}
// async fn test(_data: QueryInput) -> Response {
// error(StatusCode::OK, "error", "message")
// }
//
// async fn test2(_data: ProcedureInput) -> Response {
// error(StatusCode::OK, "error", "message")
// }
#[derive(Deserialize, Debug)]
struct CreateAccountInput {
email: Option<String>,
handle: String,
did: Option<String>,
invite_code: Option<String>,
verification_code: Option<String>,
verification_phone: Option<String>,
password: Option<String>,
recovery_key: Option<String>,
plc_op: Option<String>,
}
#[instrument]
async fn create_account(data: ProcedureInput<CreateAccountInput>) -> Response {
event!(Level::INFO, "In create_account");
error(StatusCode::OK, "error", "message")
}

View file

@ -53,7 +53,7 @@ pub fn response(code: StatusCode, message: &str) -> Response {
}
pub struct QueryInput {
parameters: HashMap<String, String>,
pub parameters: HashMap<String, String>,
}
impl<S> FromRequestParts<S> for QueryInput
where
@ -70,12 +70,16 @@ where
}
}
}
pub struct ProcedureInput {
parameters: HashMap<String, String>,
input: Json<Value>,
#[derive(Debug)]
pub struct ProcedureInput<J> {
pub parameters: HashMap<String, String>,
pub input: J,
}
impl<S> FromRequest<S> for ProcedureInput
impl<J, S> FromRequest<S> for ProcedureInput<J>
where
J: for<'de> serde::Deserialize<'de> + Send + 'static,
Bytes: FromRequest<S>,
S: Send + Sync,
{
@ -83,17 +87,13 @@ where
async fn from_request(req: Request, state: &S)
-> Result<Self, Self::Rejection> {
let query_params: Result<Query<HashMap<String, String>>, QueryRejection> = Query::try_from_uri(req.uri());
let parameters = match query_params {
Ok(p) => p.0,
Err(e) => return Err(error(StatusCode::BAD_REQUEST, "Bad Parameters", &e.body_text())),
};
let parameters: HashMap<String, String> = Query::try_from_uri(req.uri())
.map(|p| p.0)
.map_err(|e| error(StatusCode::BAD_REQUEST, "Bad Paramters", &e.body_text()))?;
let json_value = Json::<Value>::from_request(req, state).await;
let input: Json<Value> = match json_value {
Ok(v) => v,
Err(e) => return Err(error(StatusCode::BAD_REQUEST, "Bad Parameters", &e.body_text())),
};
let input: J = Json::<J>::from_request(req, state).await
.map(|Json(v)| v)
.map_err(|e| error(StatusCode::BAD_REQUEST, "Bad Parameters", &e.body_text()))?;
Ok(ProcedureInput { parameters, input })
}
@ -113,12 +113,12 @@ where
Box::pin((self)(input))
}
}
impl<F, Fut> XrpcHandler<ProcedureInput> for F
impl<J, F, Fut> XrpcHandler<ProcedureInput<J>> for F
where
F: Fn(ProcedureInput) -> Fut + Send + Sync + 'static,
F: Fn(ProcedureInput<J>) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Response> + Send + 'static,
{
fn call(&self, input: ProcedureInput)
fn call(&self, input: ProcedureInput<J>)
-> Pin<Box<dyn Future<Output = Response>+ Send>> {
Box::pin((self)(input))
}
@ -140,14 +140,15 @@ impl XrpcEndpoint {
}
}
pub fn new_procedure<P>(nsid: Nsid, procedure: P) -> Self
pub fn new_procedure<P, J>(nsid: Nsid, procedure: P) -> Self
where
P: XrpcHandler<ProcedureInput> + Clone
P: XrpcHandler<ProcedureInput<J>> + Clone,
J: for<'de> serde::Deserialize<'de> + Send + 'static,
{
XrpcEndpoint {
path: Path::Nsid(nsid),
resolver: post(async move | req: Request | -> Response {
match ProcedureInput::from_request(req, &()).await {
match ProcedureInput::<J>::from_request(req, &()).await {
Ok(pi) => procedure.call(pi).await,
Err(e) => e
}