Skip to content

Commit 4e0b7ff

Browse files
authored
Merge pull request #1259 from squidowl/renormalized-load
Renormalize Messages in `history::load`
2 parents 6c4ee6d + fb1f5c4 commit 4e0b7ff

6 files changed

Lines changed: 134 additions & 65 deletions

File tree

data/src/client.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::time::Posix;
3030
use crate::user::{ChannelUsers, Nick, NickRef};
3131
use crate::{
3232
Server, User, buffer, compression, config, ctcp, dcc, environment,
33-
file_transfer, isupport, message, mode, server,
33+
file_transfer, history, isupport, message, mode, server,
3434
};
3535

3636
pub mod on_connect;
@@ -3750,6 +3750,29 @@ impl Map {
37503750
.is_some_and(|client| client.supports_detach)
37513751
}
37523752

3753+
pub fn get_seed(&self, kind: &history::Kind) -> Option<history::Seed> {
3754+
match kind {
3755+
history::Kind::Highlights => {
3756+
let casemappings: HashMap<Server, isupport::CaseMap> = self
3757+
.servers()
3758+
.filter_map(|server| {
3759+
self.client(server)
3760+
.map(Client::casemapping)
3761+
.map(|casemapping| (server.clone(), casemapping))
3762+
})
3763+
.collect();
3764+
3765+
(!casemappings.is_empty())
3766+
.then_some(history::Seed::Multiple(casemappings))
3767+
}
3768+
_ => kind.server().and_then(|server| {
3769+
self.client(server)
3770+
.map(Client::casemapping)
3771+
.map(history::Seed::Single)
3772+
}),
3773+
}
3774+
}
3775+
37533776
pub fn get_server_handle(
37543777
&self,
37553778
server: &Server,

data/src/history.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,47 @@ pub struct Loaded {
168168
pub metadata: Metadata,
169169
}
170170

171-
pub async fn load(kind: Kind) -> Result<Loaded, Error> {
171+
pub enum Seed {
172+
Single(isupport::CaseMap),
173+
Multiple(HashMap<Server, isupport::CaseMap>),
174+
}
175+
176+
pub async fn load(kind: Kind, seed: Option<Seed>) -> Result<Loaded, Error> {
172177
let path = path(&kind).await?;
173178

174-
let messages = read_all(&path).await.unwrap_or_default();
179+
let mut messages = read_all(&path).await.unwrap_or_default();
180+
181+
if let Some(seed) = seed {
182+
// TODO: Utilize DeserializeSeed (or equivalent) so proper normalization
183+
// happens inside read_all, rather than having to renormalize afterward
184+
renormalize_messages(&mut messages, seed);
185+
}
186+
175187
let metadata = metadata::load(kind).await.unwrap_or_default();
176188

177189
Ok(Loaded { messages, metadata })
178190
}
179191

192+
pub fn renormalize_messages(messages: &mut [Message], seed: Seed) {
193+
match seed {
194+
Seed::Multiple(casemappings) => {
195+
messages.iter_mut().for_each(|message| {
196+
if let message::Target::Highlights { server, .. } =
197+
&message.target
198+
&& let Some(casemapping) = casemappings.get(server)
199+
{
200+
message.renormalize(*casemapping);
201+
}
202+
});
203+
}
204+
Seed::Single(casemapping) => {
205+
messages
206+
.iter_mut()
207+
.for_each(|message| message.renormalize(casemapping));
208+
}
209+
}
210+
}
211+
180212
pub async fn overwrite(
181213
kind: &Kind,
182214
messages: &[Message],
@@ -200,10 +232,11 @@ pub async fn overwrite(
200232

201233
pub async fn append(
202234
kind: &Kind,
235+
seed: Option<Seed>,
203236
messages: Vec<Message>,
204237
read_marker: Option<ReadMarker>,
205238
) -> Result<(), Error> {
206-
let loaded = load(kind.clone()).await?;
239+
let loaded = load(kind.clone(), seed).await?;
207240

208241
let mut all_messages = loaded.messages;
209242
messages.into_iter().for_each(|message| {
@@ -406,6 +439,7 @@ impl History {
406439
fn flush(
407440
&mut self,
408441
now: Option<Instant>,
442+
seed: Option<Seed>,
409443
) -> Option<BoxFuture<'static, Result<(), Error>>> {
410444
match self {
411445
History::Partial {
@@ -428,11 +462,11 @@ impl History {
428462
*last_updated_at = None;
429463

430464
return Some(
431-
async move {
432-
append(&kind, messages, read_marker).await
433-
}
434-
.boxed(),
435-
);
465+
async move {
466+
append(&kind, seed, messages, read_marker).await
467+
}
468+
.boxed(),
469+
);
436470
}
437471

438472
None
@@ -517,14 +551,14 @@ impl History {
517551
}
518552
}
519553

520-
async fn close(self) -> Result<(), Error> {
554+
async fn close(self, seed: Option<Seed>) -> Result<(), Error> {
521555
match self {
522556
History::Partial {
523557
kind,
524558
messages,
525559
read_marker,
526560
..
527-
} => append(&kind, messages, read_marker).await,
561+
} => append(&kind, seed, messages, read_marker).await,
528562
History::Full {
529563
kind,
530564
messages,

data/src/history/manager.rs

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ impl Manager {
6868
pub fn clear_messages(
6969
&mut self,
7070
kind: history::Kind,
71+
clients: &client::Map,
7172
) -> Option<BoxFuture<'static, Message>> {
7273
if let Some(history) = self.data.map.get_mut(&kind) {
73-
let task = history.flush(None);
74+
let task = history.flush(None, clients.get_seed(&kind));
7475

7576
match history {
7677
History::Full {
@@ -98,13 +99,17 @@ impl Manager {
9899
pub fn track(
99100
&mut self,
100101
new_resources: HashSet<Resource>,
102+
clients: Option<&client::Map>,
101103
) -> Vec<BoxFuture<'static, Message>> {
102104
let added = new_resources.difference(&self.resources).cloned();
103105
let removed = self.resources.difference(&new_resources).cloned();
104106

105107
let added = added.into_iter().map(|resource| {
108+
let seed =
109+
clients.and_then(|clients| clients.get_seed(&resource.kind));
110+
106111
async move {
107-
history::load(resource.kind.clone())
112+
history::load(resource.kind.clone(), seed)
108113
.map(move |result| Message::LoadFull(resource.kind, result))
109114
.await
110115
}
@@ -137,8 +142,6 @@ impl Manager {
137142
self.data.load_full(kind.clone(), loaded);
138143
log::debug!("loaded history for {kind}: {len} messages");
139144

140-
self.renormalize_messages(kind.clone(), clients);
141-
142145
self.process_messages(kind.clone(), clients, buffer_config);
143146

144147
return Some(Event::Loaded(kind));
@@ -212,25 +215,40 @@ impl Manager {
212215
&mut self.filters
213216
}
214217

215-
pub fn tick(&mut self, now: Instant) -> Vec<BoxFuture<'static, Message>> {
216-
self.data.flush_all(now)
218+
pub fn tick(
219+
&mut self,
220+
now: Instant,
221+
clients: &client::Map,
222+
) -> Vec<BoxFuture<'static, Message>> {
223+
self.data.flush_all(now, clients)
217224
}
218225

219226
pub fn close(
220227
&mut self,
221228
kind: history::Kind,
229+
clients: &client::Map,
222230
) -> Option<impl Future<Output = Message> + use<>> {
223231
let history = self.data.map.remove(&kind)?;
224232

225-
Some(history.close().map(|result| Message::Closed(kind, result)))
233+
Some(
234+
history
235+
.close(clients.get_seed(&kind))
236+
.map(|result| Message::Closed(kind, result)),
237+
)
226238
}
227239

228-
pub fn exit(&mut self) -> impl Future<Output = Message> + use<> {
240+
pub fn exit(
241+
&mut self,
242+
clients: &client::Map,
243+
) -> impl Future<Output = Message> + use<> {
229244
let map = std::mem::take(&mut self.data).map;
245+
let seeds: Vec<Option<history::Seed>> =
246+
map.keys().map(|kind| clients.get_seed(kind)).collect();
247+
let seeded_map = map.into_iter().zip(seeds);
230248

231249
async move {
232-
let tasks = map.into_iter().map(|(kind, state)| {
233-
state.close().map(move |result| (kind, result))
250+
let tasks = seeded_map.into_iter().map(|((kind, state), seed)| {
251+
state.close(seed).map(move |result| (kind, result))
234252
});
235253

236254
Message::Exited(future::join_all(tasks).await)
@@ -866,37 +884,18 @@ impl Manager {
866884

867885
pub fn renormalize_messages(
868886
&mut self,
869-
kind: history::Kind,
887+
kind: &history::Kind,
870888
clients: &client::Map,
871889
) {
872-
if let Some(history) = self.data.map.get_mut(&kind) {
890+
if let Some(history) = self.data.map.get_mut(kind)
891+
&& let Some(seed) = clients.get_seed(kind)
892+
{
873893
let messages = match history {
874894
History::Full { messages, .. } => messages,
875895
History::Partial { messages, .. } => messages,
876896
};
877897

878-
match kind {
879-
history::Kind::Highlights => {
880-
messages.iter_mut().for_each(|message| {
881-
if let message::Target::Highlights { server, .. } =
882-
&message.target
883-
{
884-
let casemapping = clients
885-
.get_casemapping_or_default(Some(server));
886-
887-
message.renormalize(casemapping);
888-
}
889-
});
890-
}
891-
_ => {
892-
let casemapping =
893-
clients.get_casemapping_or_default(kind.server());
894-
895-
messages
896-
.iter_mut()
897-
.for_each(|message| message.renormalize(casemapping));
898-
}
899-
}
898+
history::renormalize_messages(messages, seed);
900899
}
901900
}
902901
}
@@ -1329,16 +1328,22 @@ impl Data {
13291328
self.map.get_mut(kind).and_then(History::make_partial)
13301329
}
13311330

1332-
fn flush_all(&mut self, now: Instant) -> Vec<BoxFuture<'static, Message>> {
1331+
fn flush_all(
1332+
&mut self,
1333+
now: Instant,
1334+
clients: &client::Map,
1335+
) -> Vec<BoxFuture<'static, Message>> {
13331336
self.map
13341337
.iter_mut()
13351338
.filter_map(|(kind, state)| {
13361339
let kind = kind.clone();
13371340

1338-
state.flush(Some(now)).map(move |task| {
1339-
task.map(move |result| Message::Flushed(kind, result))
1340-
.boxed()
1341-
})
1341+
state.flush(Some(now), clients.get_seed(&kind)).map(
1342+
move |task| {
1343+
task.map(move |result| Message::Flushed(kind, result))
1344+
.boxed()
1345+
},
1346+
)
13421347
})
13431348
.collect()
13441349
}

src/buffer/input_view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ impl State {
603603
);
604604

605605
let event = history
606-
.clear_messages(kind)
606+
.clear_messages(kind, clients)
607607
.map(|history_task| Event::Cleared {
608608
history_task: Task::future(
609609
history_task,

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ impl Halloy {
401401
);
402402

403403
// Retrack after dashboard state changes
404-
let track = dashboard.track();
404+
let track = dashboard.track(Some(&self.clients));
405405

406406
let event_task = match event {
407407
Some(dashboard::Event::ConfigReloaded(config)) => {
@@ -1214,7 +1214,7 @@ impl Halloy {
12141214
}
12151215

12161216
if let Screen::Dashboard(dashboard) = &mut self.screen {
1217-
dashboard.tick(now).map(Message::Dashboard)
1217+
dashboard.tick(now, &self.clients).map(Message::Dashboard)
12181218
} else {
12191219
Task::none()
12201220
}

0 commit comments

Comments
 (0)