ed_journals/modules/state/models/state/journal_state.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
use crate::journal::JournalEvent;
use crate::state::models::resolvers::journal_state_resolver::JournalStateResolver;
use crate::state::resolvers::live_state_resolver::live_state_entry_owned::LiveStateEntryOwned;
use crate::state::StateContainer;
use std::collections::HashMap;
/// Journal state tracks both log and live events from json files. It's important to note however
/// that state that is built from the json files is volatile and is only kept in memory. To save
/// that part of the state you need to call [JournalStateResolver::all_live_state] and save the
/// contents somewhere. Then, when you create your journal state again, use the [From] trait to
/// create your instance, after which you can just feed state like normal again.
///
/// Below is a small example on how to manage this state.
///
/// ```rust,no_run
/// use std::collections::HashMap;
/// use std::fs;
/// use std::path::Path;
/// use ed_journals::journal::auto_detect_journal_path;
/// use ed_journals::journal::blocking::LiveJournalDirReader;
/// use ed_journals::state::{JournalState, LiveStateEntryOwned};
///
/// // In this example we will save the live state to a file called 'live_state.json'.
/// let path = Path::new("live_state.json");
///
/// // Check if the file exists and create either create a default state or read the file and use
/// // that instead.
/// let mut state = if path.exists() {
/// // You need to create a HashMap with strings as keys and live states as values like shown
/// // below.
/// let string_contents = fs::read_to_string(&path).unwrap();
/// let parsed: HashMap<String, LiveStateEntryOwned> = serde_json::from_str(&string_contents).unwrap();
///
/// JournalState::from(parsed)
/// } else {
/// // If the path does not exist the default state is used.
/// JournalState::default()
/// };
///
/// // From here you can just use the state how you would normally. In this example a live reader is
/// // used to read and observe changes in the journal directory.
///
/// let journal_path = auto_detect_journal_path().unwrap();
/// let mut journal_reader = LiveJournalDirReader::open(&journal_path).unwrap();
///
/// for entry in journal_reader {
/// let entry = entry.unwrap();
///
/// state.feed(&entry);
///
/// if !entry.is_live {
/// continue;
/// }
///
/// state.flush();
///
/// // In this case we save the state to a file. In this example it's done every 'live' event.
/// // Then on subsequent launches of the application it will read the contents and use that.
/// let state_contents = serde_json::to_string(&state.all_live_state()).unwrap();
/// fs::write(&path, state_contents).unwrap();
/// }
/// ```
pub type JournalState = StateContainer<JournalStateResolver, JournalEvent>;
impl From<HashMap<String, LiveStateEntryOwned>> for JournalState {
fn from(value: HashMap<String, LiveStateEntryOwned>) -> Self {
StateContainer::from(JournalStateResolver::from(value))
}
}