mpc_manager/service/
group_service.rs1use crate::state::{
7 group::{Group, GroupId},
8 parameters::Parameters,
9};
10use serde::{Deserialize, Serialize};
11use strum::{Display, EnumString};
12
13#[cfg(feature = "server")]
14use super::{notification::Notification, Service, ServiceResponse};
15#[cfg(feature = "server")]
16use crate::state::{ClientId, State};
17#[cfg(feature = "server")]
18use json_rpc2::{Error, Request};
19#[cfg(feature = "server")]
20use std::str::FromStr;
21#[cfg(feature = "server")]
22use tokio::sync::Mutex;
23
24pub const ROUTE_PREFIX: &str = "group";
26
27#[derive(Debug, Display, EnumString)]
29pub enum GroupMethod {
30 #[strum(serialize = "group_create")]
31 GroupCreate,
32 #[strum(serialize = "group_join")]
33 GroupJoin,
34}
35
36#[derive(Deserialize, Serialize)]
38pub struct GroupCreateRequest {
39 pub parameters: Parameters,
40}
41
42#[derive(Deserialize, Serialize)]
44pub struct GroupCreateResponse {
45 pub group: Group,
46}
47
48#[derive(Deserialize, Serialize)]
50pub struct GroupJoinRequest {
51 #[serde(rename = "groupId")]
52 pub group_id: GroupId,
53}
54
55#[derive(Deserialize, Serialize)]
57pub struct GroupJoinResponse {
58 pub group: Group,
59}
60
61#[cfg(feature = "server")]
64pub struct GroupService;
65
66#[axum::async_trait]
67#[cfg(feature = "server")]
68impl Service for GroupService {
69 async fn handle(
70 &self,
71 req: &Request,
72 ctx: (
73 std::sync::Arc<State>,
74 std::sync::Arc<Mutex<Vec<Notification>>>,
75 ),
76 client_id: ClientId,
77 ) -> ServiceResponse {
78 let method =
79 GroupMethod::from_str(req.method()).map_err(|_| json_rpc2::Error::MethodNotFound {
80 name: req.method().to_string(),
81 id: req.id().clone(),
82 })?;
83 let response = match method {
84 GroupMethod::GroupCreate => self.group_create(req, ctx, client_id).await?,
85 GroupMethod::GroupJoin => self.group_join(req, ctx, client_id).await?,
86 };
87 Ok(response)
88 }
89}
90
91#[cfg(feature = "server")]
92impl GroupService {
93 async fn group_create(
94 &self,
95 req: &Request,
96 ctx: (
97 std::sync::Arc<State>,
98 std::sync::Arc<Mutex<Vec<Notification>>>,
99 ),
100 client_id: ClientId,
101 ) -> ServiceResponse {
102 tracing::info!("Creating a new group");
103 let params: GroupCreateRequest = req.deserialize()?;
104 let (state, _) = ctx;
105 params
106 .parameters
107 .validate()
108 .map_err(|e| Error::InvalidParams {
109 id: req.id().clone(),
110 data: e.to_string(),
111 })?;
112
113 let group = state.add_group(params.parameters).await;
114 state
115 .join_group(group.id, client_id)
116 .await
117 .map_err(|e| Error::from(Box::from(e)))?;
118 tracing::info!(group_id = group.id().to_string(), "Group created");
119 let res = serde_json::to_value(GroupCreateResponse { group })
120 .map_err(|e| Error::from(Box::from(e)))?;
121 Ok(Some((req, res).into()))
122 }
123
124 async fn group_join(
125 &self,
126 req: &Request,
127 ctx: (
128 std::sync::Arc<State>,
129 std::sync::Arc<Mutex<Vec<Notification>>>,
130 ),
131 client_id: ClientId,
132 ) -> ServiceResponse {
133 let params: GroupJoinRequest = req.deserialize()?;
134 tracing::info!(
135 group_id = params.group_id.to_string(),
136 "Joining client to group"
137 );
138 let (state, _) = ctx;
139 let group = state
140 .join_group(params.group_id, client_id)
141 .await
142 .map_err(|e| Error::InvalidParams {
143 id: req.id().clone(),
144 data: e.to_string(),
145 })?;
146 let res = serde_json::to_value(GroupJoinResponse { group })
147 .map_err(|e| Error::from(Box::from(e)))?;
148 Ok(Some((req, res).into()))
149 }
150}