1- use std:: collections:: { BTreeSet , HashMap } ;
1+ use std:: collections:: HashMap ;
22use std:: sync:: Arc ;
3+ use json_patch:: Patch ;
34use mongodb:: bson:: doc;
45use mongodb:: bson:: oid:: ObjectId ;
5- use serde_json :: { Map , Value } ;
6+ use serde :: Serialize ;
67use tokio:: sync:: { Mutex , RwLock } ;
78use tracing:: { error, warn} ;
89use twilight_model:: id:: Id ;
@@ -11,18 +12,22 @@ use crate::context::Context;
1112use crate :: models:: config:: GuildConfig ;
1213use crate :: server:: guild:: ws:: { Connection , OutboundAction , OutboundMessage } ;
1314
15+ #[ derive( Clone , Debug , Serialize ) ]
16+ pub struct Change {
17+ pub author_id : Id < UserMarker > ,
18+ pub changes : Patch
19+ }
20+
1421struct GuildEditingState {
1522 pub connections : Vec < Arc < Connection > > ,
16- pub changes : Value ,
17- pub edited_by : BTreeSet < Id < UserMarker > >
23+ pub changes : Vec < Change > ,
1824}
1925
2026impl Default for GuildEditingState {
2127 fn default ( ) -> Self {
2228 Self {
2329 connections : vec ! [ ] ,
24- changes : Value :: Object ( Map :: new ( ) ) ,
25- edited_by : Default :: default ( ) ,
30+ changes : vec ! [ ] ,
2631 }
2732 }
2833}
@@ -59,14 +64,16 @@ impl GuildsEditing {
5964
6065 pub async fn marge_changes (
6166 & self ,
62- author : Id < UserMarker > ,
67+ author_id : Id < UserMarker > ,
6368 guild_id : Id < GuildMarker > ,
64- changes : Value
69+ changes : Patch
6570 ) -> Option < ( ) > {
6671 let guild = self . get_guild ( guild_id) . await ?;
6772 let mut guild_lock = guild. lock ( ) . await ;
68- json_patch:: merge ( & mut guild_lock. changes , & changes) ;
69- guild_lock. edited_by . insert ( author) ;
73+ guild_lock. changes . push ( Change {
74+ author_id,
75+ changes
76+ } ) ;
7077 Some ( ( ) )
7178 }
7279
@@ -75,7 +82,55 @@ impl GuildsEditing {
7582 list_lock. get ( & guild_id) . cloned ( )
7683 }
7784
78- pub async fn broadcast_changes ( & self , context : & Arc < Context > , guild_id : Id < GuildMarker > ) -> Option < ( ) > {
85+ pub async fn broadcast_users ( & self , guild_id : Id < GuildMarker > ) -> Option < ( ) > {
86+ let guild = self . get_guild ( guild_id) . await ?;
87+ let guild_lock = guild. lock ( ) . await ;
88+
89+ let users = guild_lock. connections
90+ . iter ( ) . map ( |connection| connection. user_id )
91+ . collect :: < Vec < Id < UserMarker > > > ( ) ;
92+
93+ for connection in & guild_lock. connections {
94+ let _ = connection. tx . send ( OutboundAction :: Message ( OutboundMessage :: OverwriteUsers ( users. to_owned ( ) ) ) ) ;
95+ }
96+
97+ Some ( ( ) )
98+ }
99+
100+ pub async fn broadcast_change (
101+ & self , guild_id : Id < GuildMarker > , author_id : Id < UserMarker > , changes : Patch
102+ ) -> Option < ( ) > {
103+ let guild = self . get_guild ( guild_id) . await ?;
104+ let guild_lock = guild. lock ( ) . await ;
105+
106+ for connection in & guild_lock. connections {
107+ let _ = connection. tx . send ( OutboundAction :: Message ( OutboundMessage :: PushChange ( Change {
108+ author_id,
109+ changes : changes. to_owned ( )
110+ } ) ) ) ;
111+ }
112+
113+ Some ( ( ) )
114+ }
115+
116+ pub async fn get_initialization_data ( & self , context : & Arc < Context > , guild_id : Id < GuildMarker > )
117+ -> Option < ( GuildConfig , Vec < Change > , Vec < Id < UserMarker > > ) > {
118+ let config = context. mongodb
119+ . get_config ( guild_id)
120+ . await
121+ . inspect_err ( |error| error ! ( name: "mongodb error" , ?error) )
122+ . ok ( ) ?;
123+
124+ let guild = self . get_guild ( guild_id) . await ?;
125+ let guild_lock = guild. lock ( ) . await ;
126+ let users = guild_lock. connections
127+ . iter ( ) . map ( |connection| connection. user_id )
128+ . collect :: < Vec < Id < UserMarker > > > ( ) ;
129+
130+ Some ( ( config. to_owned ( ) , guild_lock. changes . to_owned ( ) , users) )
131+ }
132+
133+ pub async fn broadcast_config_overwrite ( & self , context : & Arc < Context > , guild_id : Id < GuildMarker > ) -> Option < ( ) > {
79134 let config = context. mongodb
80135 . get_config ( guild_id)
81136 . await
@@ -89,10 +144,9 @@ impl GuildsEditing {
89144 . collect :: < Vec < Id < UserMarker > > > ( ) ;
90145
91146 for connection in & guild_lock. connections {
92- let _ = connection. tx . send ( OutboundAction :: Message ( OutboundMessage :: UpdateConfigurationData {
147+ let _ = connection. tx . send ( OutboundAction :: Message ( OutboundMessage :: OverwriteConfigurationData {
93148 saved_config : config. to_owned ( ) ,
94149 changes : guild_lock. changes . to_owned ( ) ,
95- users : users. to_owned ( ) ,
96150 } ) ) ;
97151 }
98152
@@ -112,9 +166,14 @@ impl GuildsEditing {
112166 let mut new_config = serde_json:: to_value ( config)
113167 . inspect_err ( |error| error ! ( name: "cannot convert guild config to value" , ?error) )
114168 . ok ( ) ?;
115- json_patch:: merge ( & mut new_config, & guild_lock. changes ) ;
169+ for patch in & guild_lock. changes {
170+ json_patch:: patch ( & mut new_config, & patch. changes )
171+ . inspect_err ( |error| error ! ( name: "error applying patch to guild config" , ?patch, ?error) )
172+ . ok ( ) ?;
173+ }
174+
116175 let new_config: GuildConfig = serde_json:: from_value ( new_config)
117- . inspect_err ( |error| error ! ( name: "cannot marge edits with guild config " , ?error) )
176+ . inspect_err ( |error| error ! ( name: "cannot serialize config after applying patches " , ?error) )
118177 . ok ( ) ?;
119178
120179 if new_config. guild_id != guild_id {
@@ -138,8 +197,7 @@ impl GuildsEditing {
138197 . ok ( ) ?;
139198 context. mongodb . configs_cache . remove ( & guild_id) ;
140199
141- guild_lock. changes = Value :: Object ( Map :: new ( ) ) ;
142- guild_lock. edited_by . clear ( ) ;
200+ guild_lock. changes = vec ! [ ] ;
143201
144202 Some ( ( ) )
145203 }
0 commit comments