zed/crates/collab/src/db/tables/user.rs
Marshall Bowers dacf984596
collab: Introduce UserService (#55449)
This PR introduces a `UserService` trait to Collab.

This is a step towards moving Collab away from reading user information
directly from the database.

We currently have two implementations for the trait:

- The `DatabaseUserService`, which leverages the existing query methods
to talk to the database
- The `FakeUserService`, which will be used in tests

Once we're ready, we'll be able to replace the `DatabaseUserService`
with a `CloudUserService` to fetch the users from Cloud.

Release Notes:

- N/A
2026-05-06 18:15:36 +00:00

78 lines
2 KiB
Rust

use crate::db::UserId;
use chrono::NaiveDateTime;
use rpc::proto;
use sea_orm::entity::prelude::*;
use serde::Serialize;
/// A user model.
#[derive(Clone, Debug, Default, PartialEq, Eq, DeriveEntityModel, Serialize)]
#[sea_orm(table_name = "users")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: UserId,
pub github_login: String,
pub github_user_id: i32,
pub github_user_created_at: Option<NaiveDateTime>,
pub email_address: Option<String>,
pub name: Option<String>,
pub admin: bool,
pub connected_once: bool,
pub created_at: NaiveDateTime,
}
impl From<Model> for crate::entities::User {
fn from(user: Model) -> Self {
crate::entities::User {
id: user.id,
github_login: user.github_login,
github_user_id: user.github_user_id,
name: user.name,
admin: user.admin,
connected_once: user.connected_once,
}
}
}
impl From<Model> for proto::User {
fn from(user: Model) -> Self {
Self {
id: user.id.to_proto(),
avatar_url: format!(
"https://avatars.githubusercontent.com/u/{}?s=128&v=4",
user.github_user_id
),
github_login: user.github_login,
name: user.name,
}
}
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_one = "super::room_participant::Entity")]
RoomParticipant,
#[sea_orm(has_many = "super::project::Entity")]
HostedProjects,
#[sea_orm(has_many = "super::channel_member::Entity")]
ChannelMemberships,
}
impl Related<super::room_participant::Entity> for Entity {
fn to() -> RelationDef {
Relation::RoomParticipant.def()
}
}
impl Related<super::project::Entity> for Entity {
fn to() -> RelationDef {
Relation::HostedProjects.def()
}
}
impl Related<super::channel_member::Entity> for Entity {
fn to() -> RelationDef {
Relation::ChannelMemberships.def()
}
}
impl ActiveModelBehavior for ActiveModel {}