+#[async_trait]
+impl Followable for PersonFollower {
+ type Form = PersonFollowerForm;
+ async fn follow(pool: &DbPool, form: &PersonFollowerForm) -> Result<Self, Error> {
+ use crate::schema::person_follower::dsl::{follower_id, person_follower, person_id};
+ let conn = &mut get_conn(pool).await?;
+ insert_into(person_follower)
+ .values(form)
+ .on_conflict((follower_id, person_id))
+ .do_update()
+ .set(form)
+ .get_result::<Self>(conn)
+ .await
+ }
+ async fn follow_accepted(_: &DbPool, _: CommunityId, _: PersonId) -> Result<Self, Error> {
+ unimplemented!()
+ }
+ async fn unfollow(pool: &DbPool, form: &PersonFollowerForm) -> Result<usize, Error> {
+ use crate::schema::person_follower::dsl::{follower_id, person_follower, person_id};
+ let conn = &mut get_conn(pool).await?;
+ diesel::delete(
+ person_follower
+ .filter(follower_id.eq(&form.follower_id))
+ .filter(person_id.eq(&form.person_id)),
+ )
+ .execute(conn)
+ .await
+ }
+}
+
+impl PersonFollower {
+ pub async fn list_followers(pool: &DbPool, person_id_: PersonId) -> Result<Vec<Person>, Error> {
+ use crate::schema::{person, person_follower, person_follower::person_id};
+ let conn = &mut get_conn(pool).await?;
+ person_follower::table
+ .inner_join(person::table)
+ .filter(person_id.eq(person_id_))
+ .select(person::all_columns)
+ .load(conn)
+ .await
+ }
+}
+