Decode packed event records for runtime import
This commit is contained in:
parent
83f55fa26e
commit
09b6514dbf
13 changed files with 1801 additions and 50 deletions
|
|
@ -1,11 +1,14 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::Path;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
CalendarPoint, RuntimePackedEventCollectionSummary, RuntimeSaveProfileState,
|
||||
RuntimeServiceState, RuntimeState, RuntimeWorldRestoreState, SmpLoadedSaveSlice,
|
||||
CalendarPoint, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
|
||||
RuntimePackedEventCollectionSummary, RuntimePackedEventRecordSummary,
|
||||
RuntimePackedEventTextBandSummary, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState,
|
||||
RuntimeWorldRestoreState, SmpLoadedPackedEventRecordSummary,
|
||||
SmpLoadedPackedEventTextBandSummary, SmpLoadedSaveSlice,
|
||||
};
|
||||
|
||||
pub const STATE_DUMP_FORMAT_VERSION: u32 = 1;
|
||||
|
|
@ -137,7 +140,27 @@ pub fn project_save_slice_to_runtime_state_import(
|
|||
if let Some(family) = &save_slice.bridge_family {
|
||||
metadata.insert("save_slice.bridge_family".to_string(), family.clone());
|
||||
}
|
||||
let known_company_ids = BTreeSet::new();
|
||||
let imported_event_runtime_records = save_slice
|
||||
.event_runtime_collection
|
||||
.as_ref()
|
||||
.map(|summary| {
|
||||
summary
|
||||
.records
|
||||
.iter()
|
||||
.filter_map(|record| {
|
||||
smp_packed_record_to_runtime_event_record(record, &known_company_ids)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
let packed_event_collection = save_slice.event_runtime_collection.as_ref().map(|summary| {
|
||||
let records = summary
|
||||
.records
|
||||
.iter()
|
||||
.map(runtime_packed_event_record_summary_from_smp)
|
||||
.collect::<Vec<_>>();
|
||||
RuntimePackedEventCollectionSummary {
|
||||
source_kind: summary.source_kind.clone(),
|
||||
mechanism_family: summary.mechanism_family.clone(),
|
||||
|
|
@ -148,6 +171,12 @@ pub fn project_save_slice_to_runtime_state_import(
|
|||
live_id_bound: summary.live_id_bound,
|
||||
live_record_count: summary.live_record_count,
|
||||
live_entry_ids: summary.live_entry_ids.clone(),
|
||||
decoded_record_count: records
|
||||
.iter()
|
||||
.filter(|record| record.decode_status != "unsupported_framing")
|
||||
.count(),
|
||||
imported_runtime_record_count: imported_event_runtime_records.len(),
|
||||
records,
|
||||
}
|
||||
});
|
||||
if let Some(summary) = &save_slice.event_runtime_collection {
|
||||
|
|
@ -163,6 +192,14 @@ pub fn project_save_slice_to_runtime_state_import(
|
|||
"save_slice.event_runtime_collection_record_count".to_string(),
|
||||
summary.live_record_count.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.event_runtime_collection_decoded_record_count".to_string(),
|
||||
summary.decoded_record_count.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.event_runtime_collection_imported_runtime_record_count".to_string(),
|
||||
imported_event_runtime_records.len().to_string(),
|
||||
);
|
||||
}
|
||||
let save_profile = if let Some(profile) = &save_slice.profile {
|
||||
metadata.insert(
|
||||
|
|
@ -328,7 +365,7 @@ pub fn project_save_slice_to_runtime_state_import(
|
|||
metadata,
|
||||
companies: Vec::new(),
|
||||
packed_event_collection,
|
||||
event_runtime_records: Vec::new(),
|
||||
event_runtime_records: imported_event_runtime_records,
|
||||
candidate_availability,
|
||||
special_conditions,
|
||||
service_state: RuntimeServiceState::default(),
|
||||
|
|
@ -342,6 +379,193 @@ pub fn project_save_slice_to_runtime_state_import(
|
|||
})
|
||||
}
|
||||
|
||||
fn runtime_packed_event_record_summary_from_smp(
|
||||
record: &SmpLoadedPackedEventRecordSummary,
|
||||
) -> RuntimePackedEventRecordSummary {
|
||||
RuntimePackedEventRecordSummary {
|
||||
record_index: record.record_index,
|
||||
live_entry_id: record.live_entry_id,
|
||||
payload_offset: record.payload_offset,
|
||||
payload_len: record.payload_len,
|
||||
decode_status: record.decode_status.clone(),
|
||||
trigger_kind: record.trigger_kind,
|
||||
active: record.active,
|
||||
marks_collection_dirty: record.marks_collection_dirty,
|
||||
one_shot: record.one_shot,
|
||||
text_bands: record
|
||||
.text_bands
|
||||
.iter()
|
||||
.map(runtime_packed_event_text_band_summary_from_smp)
|
||||
.collect(),
|
||||
standalone_condition_row_count: record.standalone_condition_row_count,
|
||||
grouped_effect_row_counts: record.grouped_effect_row_counts.clone(),
|
||||
decoded_actions: record.decoded_actions.clone(),
|
||||
executable_import_ready: record.executable_import_ready,
|
||||
notes: record.notes.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn runtime_packed_event_text_band_summary_from_smp(
|
||||
band: &SmpLoadedPackedEventTextBandSummary,
|
||||
) -> RuntimePackedEventTextBandSummary {
|
||||
RuntimePackedEventTextBandSummary {
|
||||
label: band.label.clone(),
|
||||
packed_len: band.packed_len,
|
||||
present: band.present,
|
||||
preview: band.preview.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn smp_packed_record_to_runtime_event_record(
|
||||
record: &SmpLoadedPackedEventRecordSummary,
|
||||
known_company_ids: &BTreeSet<u32>,
|
||||
) -> Option<Result<RuntimeEventRecord, String>> {
|
||||
if !record.executable_import_ready {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(
|
||||
smp_runtime_effects_to_runtime_effects(&record.decoded_actions, known_company_ids)
|
||||
.and_then(|effects| {
|
||||
let trigger_kind = record.trigger_kind.ok_or_else(|| {
|
||||
format!(
|
||||
"packed event record {} is missing trigger_kind",
|
||||
record.live_entry_id
|
||||
)
|
||||
})?;
|
||||
let active = record.active.ok_or_else(|| {
|
||||
format!(
|
||||
"packed event record {} is missing active flag",
|
||||
record.live_entry_id
|
||||
)
|
||||
})?;
|
||||
let marks_collection_dirty = record.marks_collection_dirty.ok_or_else(|| {
|
||||
format!(
|
||||
"packed event record {} is missing dirty flag",
|
||||
record.live_entry_id
|
||||
)
|
||||
})?;
|
||||
let one_shot = record.one_shot.ok_or_else(|| {
|
||||
format!(
|
||||
"packed event record {} is missing one_shot flag",
|
||||
record.live_entry_id
|
||||
)
|
||||
})?;
|
||||
Ok(RuntimeEventRecordTemplate {
|
||||
record_id: record.live_entry_id,
|
||||
trigger_kind,
|
||||
active,
|
||||
marks_collection_dirty,
|
||||
one_shot,
|
||||
effects,
|
||||
}
|
||||
.into_runtime_record())
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn smp_runtime_effects_to_runtime_effects(
|
||||
effects: &[RuntimeEffect],
|
||||
known_company_ids: &BTreeSet<u32>,
|
||||
) -> Result<Vec<RuntimeEffect>, String> {
|
||||
effects
|
||||
.iter()
|
||||
.map(|effect| smp_runtime_effect_to_runtime_effect(effect, known_company_ids))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn smp_runtime_effect_to_runtime_effect(
|
||||
effect: &RuntimeEffect,
|
||||
known_company_ids: &BTreeSet<u32>,
|
||||
) -> Result<RuntimeEffect, String> {
|
||||
match effect {
|
||||
RuntimeEffect::SetWorldFlag { key, value } => Ok(RuntimeEffect::SetWorldFlag {
|
||||
key: key.clone(),
|
||||
value: *value,
|
||||
}),
|
||||
RuntimeEffect::AdjustCompanyCash { target, delta } => {
|
||||
if company_target_supported_for_import(target, known_company_ids) {
|
||||
Ok(RuntimeEffect::AdjustCompanyCash {
|
||||
target: target.clone(),
|
||||
delta: *delta,
|
||||
})
|
||||
} else {
|
||||
Err("packed company-cash effect requires unresolved company ids".to_string())
|
||||
}
|
||||
}
|
||||
RuntimeEffect::AdjustCompanyDebt { target, delta } => {
|
||||
if company_target_supported_for_import(target, known_company_ids) {
|
||||
Ok(RuntimeEffect::AdjustCompanyDebt {
|
||||
target: target.clone(),
|
||||
delta: *delta,
|
||||
})
|
||||
} else {
|
||||
Err("packed company-debt effect requires unresolved company ids".to_string())
|
||||
}
|
||||
}
|
||||
RuntimeEffect::SetCandidateAvailability { name, value } => {
|
||||
Ok(RuntimeEffect::SetCandidateAvailability {
|
||||
name: name.clone(),
|
||||
value: *value,
|
||||
})
|
||||
}
|
||||
RuntimeEffect::SetSpecialCondition { label, value } => {
|
||||
Ok(RuntimeEffect::SetSpecialCondition {
|
||||
label: label.clone(),
|
||||
value: *value,
|
||||
})
|
||||
}
|
||||
RuntimeEffect::AppendEventRecord { record } => Ok(RuntimeEffect::AppendEventRecord {
|
||||
record: Box::new(smp_runtime_record_template_to_runtime(
|
||||
record,
|
||||
known_company_ids,
|
||||
)?),
|
||||
}),
|
||||
RuntimeEffect::ActivateEventRecord { record_id } => {
|
||||
Ok(RuntimeEffect::ActivateEventRecord {
|
||||
record_id: *record_id,
|
||||
})
|
||||
}
|
||||
RuntimeEffect::DeactivateEventRecord { record_id } => {
|
||||
Ok(RuntimeEffect::DeactivateEventRecord {
|
||||
record_id: *record_id,
|
||||
})
|
||||
}
|
||||
RuntimeEffect::RemoveEventRecord { record_id } => Ok(RuntimeEffect::RemoveEventRecord {
|
||||
record_id: *record_id,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn smp_runtime_record_template_to_runtime(
|
||||
record: &RuntimeEventRecordTemplate,
|
||||
known_company_ids: &BTreeSet<u32>,
|
||||
) -> Result<RuntimeEventRecordTemplate, String> {
|
||||
Ok(RuntimeEventRecordTemplate {
|
||||
record_id: record.record_id,
|
||||
trigger_kind: record.trigger_kind,
|
||||
active: record.active,
|
||||
marks_collection_dirty: record.marks_collection_dirty,
|
||||
one_shot: record.one_shot,
|
||||
effects: smp_runtime_effects_to_runtime_effects(&record.effects, known_company_ids)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn company_target_supported_for_import(
|
||||
target: &crate::RuntimeCompanyTarget,
|
||||
known_company_ids: &BTreeSet<u32>,
|
||||
) -> bool {
|
||||
match target {
|
||||
crate::RuntimeCompanyTarget::AllActive => true,
|
||||
crate::RuntimeCompanyTarget::Ids { ids } => {
|
||||
!ids.is_empty()
|
||||
&& ids
|
||||
.iter()
|
||||
.all(|company_id| known_company_ids.contains(company_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validate_runtime_state_dump_document(
|
||||
document: &RuntimeStateDumpDocument,
|
||||
) -> Result<(), String> {
|
||||
|
|
@ -397,6 +621,7 @@ pub fn load_runtime_state_import_from_str(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{StepCommand, execute_step_command};
|
||||
|
||||
fn state() -> RuntimeState {
|
||||
RuntimeState {
|
||||
|
|
@ -419,6 +644,47 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn packed_text_bands() -> Vec<crate::SmpLoadedPackedEventTextBandSummary> {
|
||||
vec![
|
||||
crate::SmpLoadedPackedEventTextBandSummary {
|
||||
label: "primary_text_band".to_string(),
|
||||
packed_len: 5,
|
||||
present: true,
|
||||
preview: "Alpha".to_string(),
|
||||
},
|
||||
crate::SmpLoadedPackedEventTextBandSummary {
|
||||
label: "secondary_text_band_0".to_string(),
|
||||
packed_len: 0,
|
||||
present: false,
|
||||
preview: "".to_string(),
|
||||
},
|
||||
crate::SmpLoadedPackedEventTextBandSummary {
|
||||
label: "secondary_text_band_1".to_string(),
|
||||
packed_len: 0,
|
||||
present: false,
|
||||
preview: "".to_string(),
|
||||
},
|
||||
crate::SmpLoadedPackedEventTextBandSummary {
|
||||
label: "secondary_text_band_2".to_string(),
|
||||
packed_len: 0,
|
||||
present: false,
|
||||
preview: "".to_string(),
|
||||
},
|
||||
crate::SmpLoadedPackedEventTextBandSummary {
|
||||
label: "secondary_text_band_3".to_string(),
|
||||
packed_len: 0,
|
||||
present: false,
|
||||
preview: "".to_string(),
|
||||
},
|
||||
crate::SmpLoadedPackedEventTextBandSummary {
|
||||
label: "secondary_text_band_4".to_string(),
|
||||
packed_len: 0,
|
||||
present: false,
|
||||
preview: "".to_string(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loads_dump_document() {
|
||||
let text = serde_json::to_string(&RuntimeStateDumpDocument {
|
||||
|
|
@ -548,6 +814,61 @@ mod tests {
|
|||
live_id_bound: 5,
|
||||
live_record_count: 3,
|
||||
live_entry_ids: vec![1, 3, 5],
|
||||
decoded_record_count: 0,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![
|
||||
crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 1,
|
||||
payload_offset: None,
|
||||
payload_len: None,
|
||||
decode_status: "unsupported_framing".to_string(),
|
||||
trigger_kind: None,
|
||||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
text_bands: Vec::new(),
|
||||
standalone_condition_row_count: 0,
|
||||
grouped_effect_row_counts: vec![0, 0, 0, 0],
|
||||
decoded_actions: Vec::new(),
|
||||
executable_import_ready: false,
|
||||
notes: vec!["test".to_string()],
|
||||
},
|
||||
crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 1,
|
||||
live_entry_id: 3,
|
||||
payload_offset: None,
|
||||
payload_len: None,
|
||||
decode_status: "unsupported_framing".to_string(),
|
||||
trigger_kind: None,
|
||||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
text_bands: Vec::new(),
|
||||
standalone_condition_row_count: 0,
|
||||
grouped_effect_row_counts: vec![0, 0, 0, 0],
|
||||
decoded_actions: Vec::new(),
|
||||
executable_import_ready: false,
|
||||
notes: vec!["test".to_string()],
|
||||
},
|
||||
crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 2,
|
||||
live_entry_id: 5,
|
||||
payload_offset: None,
|
||||
payload_len: None,
|
||||
decode_status: "unsupported_framing".to_string(),
|
||||
trigger_kind: None,
|
||||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
text_bands: Vec::new(),
|
||||
standalone_condition_row_count: 0,
|
||||
grouped_effect_row_counts: vec![0, 0, 0, 0],
|
||||
decoded_actions: Vec::new(),
|
||||
executable_import_ready: false,
|
||||
notes: vec!["test".to_string()],
|
||||
},
|
||||
],
|
||||
}),
|
||||
notes: vec!["packed profile recovered".to_string()],
|
||||
};
|
||||
|
|
@ -709,4 +1030,187 @@ mod tests {
|
|||
);
|
||||
assert!(import.state.event_runtime_records.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn projects_executable_packed_records_into_runtime_and_services_follow_on() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||
mechanism_confidence: "grounded".to_string(),
|
||||
trailer_family: None,
|
||||
bridge_family: None,
|
||||
profile: None,
|
||||
candidate_availability_table: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||
mechanism_confidence: "grounded".to_string(),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
metadata_tag_offset: 0x7100,
|
||||
records_tag_offset: 0x7200,
|
||||
close_tag_offset: 0x7600,
|
||||
packed_state_version: 0x3e9,
|
||||
packed_state_version_hex: "0x000003e9".to_string(),
|
||||
live_id_bound: 7,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![7],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 1,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 7,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(64),
|
||||
decode_status: "executable".to_string(),
|
||||
trigger_kind: Some(7),
|
||||
active: Some(true),
|
||||
marks_collection_dirty: Some(true),
|
||||
one_shot: Some(false),
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 1,
|
||||
grouped_effect_row_counts: vec![0, 1, 0, 0],
|
||||
decoded_actions: vec![
|
||||
RuntimeEffect::SetWorldFlag {
|
||||
key: "from_packed_root".to_string(),
|
||||
value: true,
|
||||
},
|
||||
RuntimeEffect::AppendEventRecord {
|
||||
record: Box::new(RuntimeEventRecordTemplate {
|
||||
record_id: 99,
|
||||
trigger_kind: 0x0a,
|
||||
active: true,
|
||||
marks_collection_dirty: false,
|
||||
one_shot: false,
|
||||
effects: vec![RuntimeEffect::SetSpecialCondition {
|
||||
label: "Imported Follow-On".to_string(),
|
||||
value: 1,
|
||||
}],
|
||||
}),
|
||||
},
|
||||
],
|
||||
executable_import_ready: true,
|
||||
notes: vec!["decoded test record".to_string()],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let mut import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"packed-events-exec",
|
||||
Some("test packed event import".to_string()),
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert_eq!(import.state.event_runtime_records.len(), 1);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.map(|summary| summary.imported_runtime_record_count),
|
||||
Some(1)
|
||||
);
|
||||
|
||||
let result = execute_step_command(
|
||||
&mut import.state,
|
||||
&StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("trigger service should succeed");
|
||||
|
||||
assert_eq!(result.final_summary.event_runtime_record_count, 2);
|
||||
assert_eq!(result.final_summary.total_event_record_service_count, 2);
|
||||
assert_eq!(result.final_summary.total_trigger_dispatch_count, 2);
|
||||
assert_eq!(result.final_summary.dirty_rerun_count, 1);
|
||||
assert_eq!(
|
||||
import.state.world_flags.get("from_packed_root"),
|
||||
Some(&true)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.special_conditions.get("Imported Follow-On"),
|
||||
Some(&1)
|
||||
);
|
||||
assert_eq!(import.state.event_runtime_records[0].service_count, 1);
|
||||
assert_eq!(import.state.event_runtime_records[1].record_id, 99);
|
||||
assert_eq!(import.state.event_runtime_records[1].service_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leaves_parity_only_packed_records_out_of_runtime_event_records() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||
mechanism_confidence: "grounded".to_string(),
|
||||
trailer_family: None,
|
||||
bridge_family: None,
|
||||
profile: None,
|
||||
candidate_availability_table: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||
mechanism_confidence: "grounded".to_string(),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
metadata_tag_offset: 0x7100,
|
||||
records_tag_offset: 0x7200,
|
||||
close_tag_offset: 0x7600,
|
||||
packed_state_version: 0x3e9,
|
||||
packed_state_version_hex: "0x000003e9".to_string(),
|
||||
live_id_bound: 7,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![7],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 7,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(48),
|
||||
decode_status: "parity_only".to_string(),
|
||||
trigger_kind: Some(7),
|
||||
active: Some(true),
|
||||
marks_collection_dirty: Some(false),
|
||||
one_shot: Some(false),
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 0,
|
||||
grouped_effect_row_counts: vec![0, 0, 0, 0],
|
||||
decoded_actions: vec![RuntimeEffect::AdjustCompanyCash {
|
||||
target: crate::RuntimeCompanyTarget::Ids { ids: vec![42] },
|
||||
delta: 50,
|
||||
}],
|
||||
executable_import_ready: false,
|
||||
notes: vec!["decoded but not importable".to_string()],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"packed-events-parity-only",
|
||||
None,
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert!(import.state.event_runtime_records.is_empty());
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.map(|summary| summary.decoded_record_count),
|
||||
Some(1)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.map(|summary| summary.imported_runtime_record_count),
|
||||
Some(0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue