plate-tool/plate-tool-eframe/src/main_state.rs

249 lines
8.9 KiB
Rust

use core::fmt;
use plate_tool_lib::plate::PlateFormat;
use plate_tool_lib::plate_instances::{self, PlateInstance};
use plate_tool_lib::transfer_region_cache::TransferRegionCache;
#[derive(Default, serde::Serialize, serde::Deserialize)]
pub struct MainState {
/// Stores all plates and transfers
///
/// It is not guaranteed that the current_* variables will refer
/// to UUIDs that exist in the lists, only that they did at one time.
/// This can happen if a plate or transfer is removed and set_* is not called.
pub source_plates: Vec<plate_tool_lib::plate_instances::PlateInstance>,
pub destination_plates: Vec<plate_tool_lib::plate_instances::PlateInstance>,
pub transfers: Vec<plate_tool_lib::transfer::Transfer>,
current_source: Option<plate_tool_lib::uuid::Uuid>,
current_destination: Option<plate_tool_lib::uuid::Uuid>,
current_transfer: Option<plate_tool_lib::uuid::Uuid>,
#[serde(skip)]
pub transfer_region_cache: plate_tool_lib::transfer_region_cache::TransferRegionCache,
}
impl MainState {
pub fn get_current_source_uuid(&self) -> Option<plate_tool_lib::uuid::Uuid> {
self.current_source
}
pub fn get_current_source_plateinstance(
&self,
) -> Option<&plate_tool_lib::plate_instances::PlateInstance> {
if let Some(id) = self.current_source {
self.source_plates.iter().find(|x| x.get_uuid() == id)
} else {
None
}
}
pub fn get_current_destination_uuid(&self) -> Option<plate_tool_lib::uuid::Uuid> {
self.current_destination
}
pub fn get_current_destination_plateinstance(
&self,
) -> Option<&plate_tool_lib::plate_instances::PlateInstance> {
if let Some(id) = self.current_destination {
self.destination_plates.iter().find(|x| x.get_uuid() == id)
} else {
None
}
}
pub fn get_current_transfer_uuid(&self) -> Option<plate_tool_lib::uuid::Uuid> {
self.current_transfer
}
pub fn get_current_transfer_info(&self) -> Option<&plate_tool_lib::transfer::Transfer> {
if let Some(id) = self.current_transfer {
self.transfers.iter().find(|x| x.get_uuid() == id)
} else {
None
}
}
pub fn get_current_source_transfers(&self) -> Option<Vec<&plate_tool_lib::transfer::Transfer>> {
let source_uuid = self.get_current_source_uuid();
if let Some(source_uuid) = source_uuid {
Some(
self.transfers
.iter()
.filter(|tr| tr.source_id == source_uuid)
.collect(),
)
} else {
None
}
}
pub fn get_current_destination_transfers(&self) -> Option<Vec<&plate_tool_lib::transfer::Transfer>> {
let destination_uuid = self.get_current_destination_uuid();
if let Some(destination_uuid) = destination_uuid {
Some(
self.transfers
.iter()
.filter(|tr| tr.dest_id == destination_uuid)
.collect(),
)
} else {
None
}
}
pub fn set_current_source(&mut self, id: plate_tool_lib::uuid::Uuid) -> bool {
if self.check_source_exists(id) {
self.current_source = Some(id);
self.set_no_current_transfer();
true
} else {
false
}
}
pub fn set_current_destination(&mut self, id: plate_tool_lib::uuid::Uuid) -> bool {
if self.check_destination_exists(id) {
self.current_destination = Some(id);
self.set_no_current_transfer();
true
} else {
false
}
}
pub fn set_current_transfer(&mut self, id: plate_tool_lib::uuid::Uuid) -> bool {
if let Some(tr) = self.transfers.iter().find(|x| x.get_uuid() == id) {
let source_exists = self.check_source_exists(tr.source_id);
let destination_exists = self.check_destination_exists(tr.dest_id);
if source_exists && destination_exists {
self.current_transfer = Some(id);
self.current_source = Some(tr.source_id);
self.current_destination = Some(tr.dest_id);
}
true
} else {
false
}
}
pub fn set_no_current_source(&mut self) {
self.current_source = None;
}
pub fn set_no_current_destination(&mut self) {
self.current_destination = None;
}
pub fn set_no_current_transfer(&mut self) {
self.current_transfer = None;
}
fn check_source_exists(&self, id: plate_tool_lib::uuid::Uuid) -> bool {
self.source_plates
.iter()
.map(|x| x.get_uuid())
.find(|x| *x == id)
.is_some()
}
pub fn get_source_by_uuid(&self, id: plate_tool_lib::uuid::Uuid) -> Option<&PlateInstance> {
self.source_plates
.iter()
.find(|x| x.get_uuid() == id)
}
fn check_destination_exists(&self, id: plate_tool_lib::uuid::Uuid) -> bool {
self.destination_plates
.iter()
.map(|x| x.get_uuid())
.find(|x| *x == id)
.is_some()
}
pub fn get_destination_by_uuid(&self, id: plate_tool_lib::uuid::Uuid) -> Option<&PlateInstance> {
self.destination_plates
.iter()
.find(|x| x.get_uuid() == id)
}
}
impl fmt::Debug for MainState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
#[derive(Debug)]
#[allow(dead_code)]
struct SelectedFields<'a> {
pub source_plates: &'a Vec<plate_tool_lib::plate_instances::PlateInstance>,
pub destination_plates: &'a Vec<plate_tool_lib::plate_instances::PlateInstance>,
pub transfers: &'a Vec<plate_tool_lib::transfer::Transfer>,
current_source: &'a Option<plate_tool_lib::uuid::Uuid>,
current_destination: &'a Option<plate_tool_lib::uuid::Uuid>,
current_transfer: &'a Option<plate_tool_lib::uuid::Uuid>,
}
let Self {
source_plates,
destination_plates,
transfers,
current_source,
current_destination,
current_transfer,
transfer_region_cache: _,
} = self;
fmt::Debug::fmt(
&SelectedFields {
source_plates,
destination_plates,
transfers,
current_source,
current_destination,
current_transfer,
},
f,
)
}
}
pub fn construct_fake_mainstate() -> MainState {
let src_plate: plate_tool_lib::plate_instances::PlateInstance =
plate_instances::PlateInstance::new(
plate_tool_lib::plate::PlateType::Source,
PlateFormat::W96,
"src1".to_owned(),
);
let dest_plate: plate_tool_lib::plate_instances::PlateInstance =
plate_instances::PlateInstance::new(
plate_tool_lib::plate::PlateType::Destination,
PlateFormat::W96,
"dest1".to_owned(),
);
let well_a1 = plate_tool_lib::Well { row: 1, col: 1 };
let well_c3 = plate_tool_lib::Well { row: 3, col: 3 };
let well_a5 = plate_tool_lib::Well { row: 1, col: 5 };
let transfer1_region: plate_tool_lib::transfer_region::TransferRegion =
plate_tool_lib::transfer_region::TransferRegion {
source_plate: src_plate.plate,
source_region: plate_tool_lib::transfer_region::Region::Rect(well_a1, well_c3),
dest_plate: dest_plate.plate,
dest_region: plate_tool_lib::transfer_region::Region::Point(well_a1),
interleave_source: (1, 1),
interleave_dest: (1, 1),
};
let transfer1: plate_tool_lib::transfer::Transfer = plate_tool_lib::transfer::Transfer::new(
src_plate.clone(),
dest_plate.clone(),
transfer1_region,
"Shrimp".to_owned(),
);
let transfer2_region: plate_tool_lib::transfer_region::TransferRegion =
plate_tool_lib::transfer_region::TransferRegion {
source_plate: src_plate.plate,
source_region: plate_tool_lib::transfer_region::Region::Rect(well_a1, well_c3),
dest_plate: dest_plate.plate,
dest_region: plate_tool_lib::transfer_region::Region::Point(well_a5),
interleave_source: (1, 1),
interleave_dest: (2, 2),
};
let transfer2: plate_tool_lib::transfer::Transfer = plate_tool_lib::transfer::Transfer::new(
src_plate.clone(),
dest_plate.clone(),
transfer2_region,
"Shrimp".to_owned(),
);
MainState {
source_plates: vec![src_plate],
destination_plates: vec![dest_plate],
transfers: vec![transfer1, transfer2],
current_source: None,
current_destination: None,
current_transfer: None,
transfer_region_cache: TransferRegionCache::default(),
}
}