diff --git a/src/activitystream/actor.rs b/src/activitystream/actor.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/activitystream/object.rs b/src/activitystream/object.rs index b3941c02..accddcd7 100644 --- a/src/activitystream/object.rs +++ b/src/activitystream/object.rs @@ -70,7 +70,7 @@ impl Object for serde_json::Value { todo!() } - // ... + // ... TODO! } impl Link for serde_json::Value { @@ -78,5 +78,26 @@ impl Link for serde_json::Value { self.get("href")?.as_str() } - // ... + // ... TODO! +} + +pub trait ToJson : Object { + fn json(&self) -> serde_json::Value; +} + +impl ToJson for T where T : Object { + fn json(&self) -> serde_json::Value { + let mut map = serde_json::Map::new(); + + if let Some(id) = self.id() { + map.insert( + "id".to_string(), + serde_json::Value::String(id.to_string()) + ); + } + + // ... TODO! + + serde_json::Value::Object(map) + } } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 00000000..138ccb49 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,52 @@ +use std::ops::Deref; +use std::sync::Arc; + +use crate::activitystream::object::ToJson; +use crate::activitystream::{types::ActivityType, Object, Type}; +use crate::model::user; +use axum::{extract::{Path, State}, http::StatusCode, routing::{get, post}, Json, Router}; +use sea_orm::{DatabaseConnection, EntityTrait}; + +pub async fn serve(db: DatabaseConnection) { + // build our application with a single route + let app = Router::new() + .route("/inbox", post(inbox)) + .route("/outbox", get(|| async { todo!() })) + .route("/users/:id", get(user)) + .route("/objects/:id", get(object)) + .with_state(Arc::new(db)); + + // run our app with hyper, listening globally on port 3000 + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + + axum::serve(listener, app) + .await + .unwrap(); +} + +async fn inbox(State(_db) : State>, Json(object): Json) -> Result, StatusCode> { + match object.object_type() { + None => { Err(StatusCode::BAD_REQUEST) }, + Some(Type::Activity) => { Err(StatusCode::UNPROCESSABLE_ENTITY) }, + Some(Type::ActivityType(ActivityType::Follow)) => { todo!() }, + Some(Type::ActivityType(ActivityType::Create)) => { todo!() }, + Some(Type::ActivityType(ActivityType::Like)) => { todo!() }, + Some(Type::ActivityType(_x)) => { Err(StatusCode::NOT_IMPLEMENTED) }, + Some(_x) => { Err(StatusCode::UNPROCESSABLE_ENTITY) } + } +} + +async fn user(State(db) : State>, Path(id): Path) -> Result, StatusCode> { + match user::Entity::find_by_id(id).one(db.deref()).await { + Ok(Some(user)) => Ok(Json(user.json())), + Ok(None) => Err(StatusCode::NOT_FOUND), + Err(e) => { + tracing::error!("error querying for user: {e}"); + Err(StatusCode::INTERNAL_SERVER_ERROR) + }, + } +} + +async fn object(State(_db) : State>, Path(_id): Path) -> Result, StatusCode> { + todo!() +}