ed_journals/modules/state/models/resolvers/
journal_state_resolver.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
pub mod journal_commander_entry;

use std::collections::HashMap;

use serde::Serialize;

use crate::journal::{JournalEvent, JournalEventKind};
use crate::logs::LogEventContent;
use crate::state::models::feed_result::FeedResult;
use crate::state::models::resolvers::journal_state_resolver::journal_commander_entry::JournalCommanderEntry;
use crate::state::resolvers::live_state_resolver::live_state_entry::LiveStateEntry;
use crate::state::resolvers::live_state_resolver::live_state_entry_owned::LiveStateEntryOwned;
use crate::state::traits::state_resolver::StateResolver;
use crate::state::LogState;

/// State which tracks both log events and events that are fired when a json file updates.
#[derive(Serialize, Default)]
pub struct JournalStateResolver {
    pub commanders: HashMap<String, JournalCommanderEntry>,
    current_commander_id: Option<String>,
}

impl StateResolver<JournalEvent> for JournalStateResolver {
    fn feed(&mut self, input: &JournalEvent) -> FeedResult {
        if let JournalEventKind::LogEvent(log_event) = &input.kind {
            if let LogEventContent::Commander(commander) = &log_event.content {
                self.current_commander_id = Some(commander.fid.to_string());

                if !self.commanders.contains_key(&commander.fid) {
                    self.commanders
                        .insert(commander.fid.to_string(), JournalCommanderEntry::default());
                }
            }

            let Some(current_commander) = self.current_commander_mut() else {
                return FeedResult::Later;
            };

            current_commander.log_state.feed(log_event);
        }

        let Some(current_commander) = self.current_commander_mut() else {
            return FeedResult::Later;
        };

        current_commander.live_state.feed(input);

        FeedResult::Accepted
    }
}

impl From<HashMap<String, LiveStateEntryOwned>> for JournalStateResolver {
    fn from(value: HashMap<String, LiveStateEntryOwned>) -> Self {
        Self {
            commanders: value
                .into_iter()
                .map(|(key, entry)| {
                    (
                        key,
                        JournalCommanderEntry {
                            name: entry.name,
                            log_state: LogState::default(),
                            live_state: entry.state,
                        },
                    )
                })
                .collect(),
            current_commander_id: None,
        }
    }
}

impl JournalStateResolver {
    pub fn current_commander(&self) -> Option<&JournalCommanderEntry> {
        self.current_commander_id
            .as_ref()
            .and_then(|commander_id| self.commanders.get(commander_id))
    }

    pub fn current_commander_mut(&mut self) -> Option<&mut JournalCommanderEntry> {
        self.current_commander_id
            .as_ref()
            .and_then(|commander_id| self.commanders.get_mut(commander_id))
    }

    pub fn all_live_state(&self) -> HashMap<&String, LiveStateEntry> {
        self.commanders
            .iter()
            .map(|(key, value)| {
                (
                    key,
                    LiveStateEntry {
                        name: &value.name,
                        state: &value.live_state,
                    },
                )
            })
            .collect()
    }
}