use crate::app::event::Event;
use crate::app::state::{Consumed, SessionHelper};
use crate::app::{AeonError, DynError};
use crate::sketchbook::data_structs::{ChangeIdData, ObservationData};
use crate::sketchbook::event_utils::{make_reversible, mk_obs_event, mk_obs_state_change};
use crate::sketchbook::ids::{DatasetId, ObservationId};
use crate::sketchbook::observations::{Dataset, Observation};
use crate::sketchbook::JsonSerde;
const REMOVE_OBSERVATION_PATH: &str = "remove";
const SET_OBSERVATION_ID_PATH: &str = "set_id";
const SET_OBSERVATION_DATA_PATH: &str = "set_data";
impl SessionHelper for Dataset {}
impl Dataset {
pub(in crate::sketchbook::observations) fn event_push_observation(
&mut self,
event: &Event,
dataset_id: DatasetId,
) -> Result<Consumed, DynError> {
let component_name = "observations/dataset";
let payload = Self::clone_payload_str(event, component_name)?;
let observation_data = ObservationData::from_json_str(payload.as_str())?;
let observation = observation_data.to_observation()?;
self.push_obs(observation)?;
let state_change = mk_obs_state_change(&["push_obs"], &observation_data);
let reverse_at_path = [dataset_id.as_str(), "pop_obs"];
let reverse_event = mk_obs_event(&reverse_at_path, None);
Ok(make_reversible(state_change, event, reverse_event))
}
pub(in crate::sketchbook::observations) fn event_push_empty_observation(
&mut self,
event: &Event,
dataset_id: DatasetId,
) -> Result<Consumed, DynError> {
let id = self.generate_obs_id("obs", Some(1));
let observation = Observation::new_full_unspecified(self.num_variables(), id.as_str())?;
let observation_data = ObservationData::from_obs(&observation, &dataset_id);
self.push_obs(observation)?;
let state_change = mk_obs_state_change(&["push_obs"], &observation_data);
let reverse_at_path = [dataset_id.as_str(), "pop_obs"];
let reverse_event = mk_obs_event(&reverse_at_path, None);
Ok(make_reversible(state_change, event, reverse_event))
}
pub(in crate::sketchbook::observations) fn event_pop_observation(
&mut self,
event: &Event,
dataset_id: DatasetId,
) -> Result<Consumed, DynError> {
if self.num_observations() == 0 {
return Ok(Consumed::NoChange); }
let last_obs = self.observations.last().unwrap();
let obs_data = ObservationData::from_obs(last_obs, &dataset_id);
self.pop_obs();
let state_change = mk_obs_state_change(&["pop_obs"], &obs_data);
let reverse_at_path = [dataset_id.as_str(), "push_obs"];
let payload = obs_data.to_json_str();
let reverse_event = mk_obs_event(&reverse_at_path, Some(&payload));
Ok(make_reversible(state_change, event, reverse_event))
}
pub(in crate::sketchbook::observations) fn event_modify_observation(
&mut self,
event: &Event,
action: &str,
dataset_id: DatasetId,
obs_id: ObservationId,
) -> Result<Consumed, DynError> {
let component_name = "observations/dataset";
match action {
REMOVE_OBSERVATION_PATH => {
let original_obs = self.get_obs(&obs_id)?.clone();
let obs_data = ObservationData::from_obs(&original_obs, &dataset_id);
self.remove_obs(&obs_id)?;
let state_change = mk_obs_state_change(&["remove_obs"], &obs_data);
Ok(Consumed::Irreversible {
state_change,
reset: true,
})
}
SET_OBSERVATION_ID_PATH => {
let new_id = Self::clone_payload_str(event, component_name)?;
if obs_id.as_str() == new_id.as_str() {
return Ok(Consumed::NoChange);
}
self.set_obs_id_by_str(obs_id.as_str(), new_id.as_str())?;
let id_change_data = ChangeIdData::new_with_metadata(
obs_id.as_str(),
new_id.as_str(),
dataset_id.as_str(),
);
let state_change = mk_obs_state_change(&["set_obs_id"], &id_change_data);
let reverse_at_path = [
dataset_id.as_str(),
new_id.as_str(),
SET_OBSERVATION_ID_PATH,
];
let reverse_event = mk_obs_event(&reverse_at_path, Some(obs_id.as_str()));
Ok(make_reversible(state_change, event, reverse_event))
}
SET_OBSERVATION_DATA_PATH => {
let payload = Self::clone_payload_str(event, component_name)?;
let new_obs_data = ObservationData::from_json_str(&payload)?;
let new_obs = new_obs_data.to_observation()?;
let orig_obs = self.get_obs(&obs_id)?;
if orig_obs == &new_obs {
return Ok(Consumed::NoChange);
}
let orig_obs_data = ObservationData::from_obs(orig_obs, &dataset_id);
self.set_observation_raw(&obs_id, new_obs)?;
let state_change = mk_obs_state_change(&["set_obs_data"], &new_obs_data);
let reverse_at_path = [
dataset_id.as_str(),
obs_id.as_str(),
SET_OBSERVATION_DATA_PATH,
];
let payload = orig_obs_data.to_json_str();
let reverse_event = mk_obs_event(&reverse_at_path, Some(&payload));
Ok(make_reversible(state_change, event, reverse_event))
}
_ => AeonError::throw(format!(
"`{component_name}` cannot perform action `{action}`."
)),
}
}
}