i love clippy

This commit is contained in:
Emilia Allison 2023-06-08 11:57:03 -04:00
parent af5bbd466c
commit c88a34595e
Signed by: emilia
GPG Key ID: 7A3F8997BFE894E0
11 changed files with 114 additions and 135 deletions

View File

@ -56,7 +56,6 @@ pub fn MainWindow() -> Html {
let new_button_callback = { let new_button_callback = {
let main_dispatch = main_dispatch.clone(); let main_dispatch = main_dispatch.clone();
let ct_dispatch = ct_dispatch.clone();
Callback::from(move |_| { Callback::from(move |_| {
let window = web_sys::window().unwrap(); let window = web_sys::window().unwrap();
let confirm = let confirm =
@ -73,12 +72,12 @@ pub fn MainWindow() -> Html {
let export_csv_button_callback = { let export_csv_button_callback = {
let main_state = main_state.clone(); let main_state = main_state.clone();
Callback::from(move |_| { Callback::from(move |_| {
if main_state.transfers.len() == 0 { if main_state.transfers.is_empty() {
web_sys::window() web_sys::window()
.unwrap() .unwrap()
.alert_with_message("No transfers to export.") .alert_with_message("No transfers to export.")
.unwrap(); .unwrap();
return (); return;
} }
web_sys::window().unwrap().alert_with_message("CSV export is currently not importable. Export as JSON if you'd like to back up your work!").unwrap(); web_sys::window().unwrap().alert_with_message("CSV export is currently not importable. Export as JSON if you'd like to back up your work!").unwrap();
if let Ok(csv) = state_to_csv(&main_state) { if let Ok(csv) = state_to_csv(&main_state) {
@ -88,7 +87,6 @@ pub fn MainWindow() -> Html {
}; };
let export_json_button_callback = { let export_json_button_callback = {
let main_state = main_state.clone();
Callback::from(move |_| { Callback::from(move |_| {
if let Ok(json) = serde_json::to_string(&main_state) { if let Ok(json) = serde_json::to_string(&main_state) {
save_str(&json, "plate-tool-state.json"); save_str(&json, "plate-tool-state.json");
@ -102,7 +100,6 @@ pub fn MainWindow() -> Html {
}; };
let import_json_button_callback = { let import_json_button_callback = {
let main_dispatch = main_dispatch.clone();
Callback::from(move |_| { Callback::from(move |_| {
let window = web_sys::window().unwrap(); let window = web_sys::window().unwrap();
let document = window.document().unwrap(); let document = window.document().unwrap();
@ -119,7 +116,7 @@ pub fn MainWindow() -> Html {
modal.remove(); modal.remove();
}) })
}; };
modal.set_onclose(Some(&onclose_callback.as_ref().unchecked_ref())); modal.set_onclose(Some(onclose_callback.as_ref().unchecked_ref()));
onclose_callback.forget(); onclose_callback.forget();
let form = document let form = document
@ -164,14 +161,14 @@ pub fn MainWindow() -> Html {
modal.close(); modal.close();
} }
}); });
fr.set_onload(Some(&onload.as_ref().unchecked_ref())); fr.set_onload(Some(onload.as_ref().unchecked_ref()));
onload.forget(); // Magic (don't touch) onload.forget(); // Magic (don't touch)
} }
} }
} }
}) })
}; };
input.set_onchange(Some(&input_callback.as_ref().unchecked_ref())); input.set_onchange(Some(input_callback.as_ref().unchecked_ref()));
input_callback.forget(); // Magic straight from the docs, don't touch :( input_callback.forget(); // Magic straight from the docs, don't touch :(
modal.append_child(&form).unwrap(); modal.append_child(&form).unwrap();

View File

@ -18,7 +18,6 @@ pub fn NewPlateDialog(props: &NewPlateDialogProps) -> Html {
let (_, dispatch) = use_store::<MainState>(); let (_, dispatch) = use_store::<MainState>();
let new_plate_callback = { let new_plate_callback = {
let dispatch = dispatch.clone();
let close_callback = props.close_callback.clone(); let close_callback = props.close_callback.clone();
Callback::from(move |e: SubmitEvent| { Callback::from(move |e: SubmitEvent| {
e.prevent_default(); e.prevent_default();

View File

@ -27,8 +27,6 @@ pub fn DestinationPlate(props: &DestinationPlateProps) -> Html {
let m_start_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None); let m_start_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None);
let m_end_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None); let m_end_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None);
let m_stat_handle: UseStateHandle<bool> = use_state_eq(|| false); let m_stat_handle: UseStateHandle<bool> = use_state_eq(|| false);
let m_start = m_start_handle.clone();
let m_end = m_end_handle.clone();
if !(*m_stat_handle) { if !(*m_stat_handle) {
let (pt1, pt2) = match ct_state.transfer.transfer_region.dest_region { let (pt1, pt2) = match ct_state.transfer.transfer_region.dest_region {
@ -46,12 +44,12 @@ pub fn DestinationPlate(props: &DestinationPlateProps) -> Html {
let m_stat_handle = m_stat_handle.clone(); let m_stat_handle = m_stat_handle.clone();
Callback::from(move |(i, j, t)| match t { Callback::from(move |(i, j, t)| match t {
MouseEventType::MOUSEDOWN => { MouseEventType::Mousedown => {
m_start_handle.set(Some((i, j))); m_start_handle.set(Some((i, j)));
m_end_handle.set(Some((i, j))); m_end_handle.set(Some((i, j)));
m_stat_handle.set(true); m_stat_handle.set(true);
} }
MouseEventType::MOUSEENTER => { MouseEventType::Mouseenter => {
if *m_stat_handle { if *m_stat_handle {
m_end_handle.set(Some((i, j))); m_end_handle.set(Some((i, j)));
} }
@ -79,7 +77,6 @@ pub fn DestinationPlate(props: &DestinationPlateProps) -> Html {
let mouseup_callback = { let mouseup_callback = {
let m_start_handle = m_start_handle.clone(); let m_start_handle = m_start_handle.clone();
let m_end_handle = m_end_handle.clone(); let m_end_handle = m_end_handle.clone();
let m_stat_handle = m_stat_handle.clone();
Callback::from(move |_: MouseEvent| { Callback::from(move |_: MouseEvent| {
m_stat_handle.set(false); m_stat_handle.set(false);
@ -111,10 +108,10 @@ pub fn DestinationPlate(props: &DestinationPlateProps) -> Html {
let row = (1..=props.destination_plate.plate.size().1).map(|j| { let row = (1..=props.destination_plate.plate.size().1).map(|j| {
html! { html! {
<DestPlateCell i={i} j={j} <DestPlateCell i={i} j={j}
selected={super::source_plate::in_rect(*m_start.clone(), *m_end.clone(), (i,j))} selected={super::source_plate::in_rect(*m_start_handle.clone(), *m_end_handle.clone(), (i,j))}
mouse={mouse_callback.clone()} mouse={mouse_callback.clone()}
in_transfer={destination_wells.contains(&(i,j))} in_transfer={destination_wells.contains(&(i,j))}
color={color_map.get(&(i,j)).map(|x| *x).and_then(|y| Some((y,color_counter)))} color={color_map.get(&(i,j)).copied().map(|y| (y,color_counter))}
/> />
} }
}).collect::<Html>(); }).collect::<Html>();
@ -143,8 +140,8 @@ pub fn DestinationPlate(props: &DestinationPlateProps) -> Html {
#[derive(Debug)] #[derive(Debug)]
pub enum MouseEventType { pub enum MouseEventType {
MOUSEDOWN, Mousedown,
MOUSEENTER, Mouseenter,
} }
#[derive(Properties, PartialEq)] #[derive(Properties, PartialEq)]
@ -173,15 +170,15 @@ fn DestPlateCell(props: &DestPlateCellProps) -> Html {
}; };
let mouse = Callback::clone(&props.mouse); let mouse = Callback::clone(&props.mouse);
let mouse2 = Callback::clone(&props.mouse); let mouse2 = Callback::clone(&props.mouse);
let (i, j) = (props.i.clone(), props.j.clone()); let (i, j) = (props.i, props.j);
html! { html! {
<td class={classes!("plate_cell", selected_class, in_transfer_class)} <td class={classes!("plate_cell", selected_class, in_transfer_class)}
onmousedown={move |_| { onmousedown={move |_| {
mouse.emit((i,j, MouseEventType::MOUSEDOWN)) mouse.emit((i,j, MouseEventType::Mousedown))
}} }}
onmouseenter={move |_| { onmouseenter={move |_| {
mouse2.emit((i,j, MouseEventType::MOUSEENTER)) mouse2.emit((i,j, MouseEventType::Mouseenter))
}}> }}>
<div class="plate_cell_inner" <div class="plate_cell_inner"
style={format!("background: rgba({},{},{},1);", color[0], color[1], color[2])}/> style={format!("background: rgba({},{},{},1);", color[0], color[1], color[2])}/>

View File

@ -27,8 +27,6 @@ pub fn SourcePlate(props: &SourcePlateProps) -> Html {
let m_start_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None); let m_start_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None);
let m_end_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None); let m_end_handle: UseStateHandle<Option<(u8, u8)>> = use_state_eq(|| None);
let m_stat_handle: UseStateHandle<bool> = use_state_eq(|| false); let m_stat_handle: UseStateHandle<bool> = use_state_eq(|| false);
let m_start = m_start_handle.clone();
let m_end = m_end_handle.clone();
if !(*m_stat_handle) { if !(*m_stat_handle) {
let (pt1, pt2) = match ct_state.transfer.transfer_region.source_region { let (pt1, pt2) = match ct_state.transfer.transfer_region.source_region {
@ -64,12 +62,12 @@ pub fn SourcePlate(props: &SourcePlateProps) -> Html {
let m_stat_handle = m_stat_handle.clone(); let m_stat_handle = m_stat_handle.clone();
Callback::from(move |(i, j, t)| match t { Callback::from(move |(i, j, t)| match t {
MouseEventType::MOUSEDOWN => { MouseEventType::Mousedown => {
m_start_handle.set(Some((i, j))); m_start_handle.set(Some((i, j)));
m_end_handle.set(Some((i, j))); m_end_handle.set(Some((i, j)));
m_stat_handle.set(true); m_stat_handle.set(true);
} }
MouseEventType::MOUSEENTER => { MouseEventType::Mouseenter => {
if *m_stat_handle { if *m_stat_handle {
m_end_handle.set(Some((i, j))); m_end_handle.set(Some((i, j)));
} }
@ -80,7 +78,6 @@ pub fn SourcePlate(props: &SourcePlateProps) -> Html {
let mouseup_callback = { let mouseup_callback = {
let m_start_handle = m_start_handle.clone(); let m_start_handle = m_start_handle.clone();
let m_end_handle = m_end_handle.clone(); let m_end_handle = m_end_handle.clone();
let m_stat_handle = m_stat_handle.clone();
Callback::from(move |_: MouseEvent| { Callback::from(move |_: MouseEvent| {
m_stat_handle.set(false); m_stat_handle.set(false);
@ -113,10 +110,10 @@ pub fn SourcePlate(props: &SourcePlateProps) -> Html {
.map(|j| { .map(|j| {
html! { html! {
<SourcePlateCell i={i} j={j} <SourcePlateCell i={i} j={j}
selected={in_rect(*m_start.clone(), *m_end.clone(), (i,j))} selected={in_rect(*m_start_handle.clone(), *m_end_handle.clone(), (i,j))}
mouse={mouse_callback.clone()} mouse={mouse_callback.clone()}
in_transfer={source_wells.contains(&(i,j))} in_transfer={source_wells.contains(&(i,j))}
color={color_map.get(&(i,j)).map(|x| *x).and_then(|y| Some((y,color_counter)))} color={color_map.get(&(i,j)).copied().map(|y| (y,color_counter))}
/> />
} }
}) })
@ -156,8 +153,8 @@ pub struct SourcePlateCellProps {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum MouseEventType { pub enum MouseEventType {
MOUSEDOWN, Mousedown,
MOUSEENTER, Mouseenter,
} }
#[function_component] #[function_component]
@ -176,16 +173,16 @@ fn SourcePlateCell(props: &SourcePlateCellProps) -> Html {
}; };
let mouse = Callback::clone(&props.mouse); let mouse = Callback::clone(&props.mouse);
let mouse2 = Callback::clone(&props.mouse); let mouse2 = Callback::clone(&props.mouse);
let (i, j) = (props.i.clone(), props.j.clone()); let (i, j) = (props.i, props.j);
html! { html! {
<td class={classes!("plate_cell", selected_class, in_transfer_class)} <td class={classes!("plate_cell", selected_class, in_transfer_class)}
id={format!("color={:?}", props.color)} id={format!("color={:?}", props.color)}
onmousedown={move |_| { onmousedown={move |_| {
mouse.emit((i,j, MouseEventType::MOUSEDOWN)) mouse.emit((i,j, MouseEventType::Mousedown))
}} }}
onmouseenter={move |_| { onmouseenter={move |_| {
mouse2.emit((i,j, MouseEventType::MOUSEENTER)) mouse2.emit((i,j, MouseEventType::Mouseenter))
}}> }}>
<div class="plate_cell_inner" <div class="plate_cell_inner"
style={format!("background: rgba({},{},{},1);", color[0], color[1], color[2])}/> style={format!("background: rgba({},{},{},1);", color[0], color[1], color[2])}/>
@ -195,12 +192,12 @@ fn SourcePlateCell(props: &SourcePlateCellProps) -> Html {
pub fn in_rect(corner1: Option<(u8, u8)>, corner2: Option<(u8, u8)>, pt: (u8, u8)) -> bool { pub fn in_rect(corner1: Option<(u8, u8)>, corner2: Option<(u8, u8)>, pt: (u8, u8)) -> bool {
if let (Some(c1), Some(c2)) = (corner1, corner2) { if let (Some(c1), Some(c2)) = (corner1, corner2) {
return pt.0 <= u8::max(c1.0, c2.0) pt.0 <= u8::max(c1.0, c2.0)
&& pt.0 >= u8::min(c1.0, c2.0) && pt.0 >= u8::min(c1.0, c2.0)
&& pt.1 <= u8::max(c1.1, c2.1) && pt.1 <= u8::max(c1.1, c2.1)
&& pt.1 >= u8::min(c1.1, c2.1); && pt.1 >= u8::min(c1.1, c2.1)
} else { } else {
return false; false
} }
} }

View File

@ -17,9 +17,12 @@ impl ColorPalette {
pub fn get(&self, t: f64) -> [f64; 3] { pub fn get(&self, t: f64) -> [f64; 3] {
[ [
(self.a[0] + self.b[0] * f64::cos(6.28318 * (self.c[0] * t + self.d[0]))) * 255.0, (self.a[0] + self.b[0] * f64::cos(std::f64::consts::TAU * (self.c[0] * t + self.d[0])))
(self.a[1] + self.b[1] * f64::cos(6.28318 * (self.c[1] * t + self.d[1]))) * 255.0, * 255.0,
(self.a[2] + self.b[2] * f64::cos(6.28318 * (self.c[2] * t + self.d[2]))) * 255.0, (self.a[1] + self.b[1] * f64::cos(std::f64::consts::TAU * (self.c[1] * t + self.d[1])))
* 255.0,
(self.a[2] + self.b[2] * f64::cos(std::f64::consts::TAU * (self.c[2] * t + self.d[2])))
* 255.0,
] ]
} }

View File

@ -41,20 +41,15 @@ impl Store for MainState {
impl MainState { impl MainState {
pub fn _purge_transfers(&mut self) { pub fn _purge_transfers(&mut self) {
// Removes any transfers for which the associated plates are gone // Removes any transfers for which the associated plates are gone
self.transfers = self self.transfers.retain(|tr| {
.transfers self.source_plates
.iter() .iter()
.filter(|tr| { .any(|spi| spi.get_uuid() == tr.source_id)
self.source_plates && self
.destination_plates
.iter() .iter()
.any(|spi| spi.get_uuid() == tr.source_id) .any(|dpi| dpi.get_uuid() == tr.dest_id)
&& self });
.destination_plates
.iter()
.any(|dpi| dpi.get_uuid() == tr.dest_id)
})
.map(|tr| tr.clone())
.collect();
} }
pub fn add_source_plate(&mut self, plate: PlateInstance) { pub fn add_source_plate(&mut self, plate: PlateInstance) {

View File

@ -26,10 +26,10 @@ pub fn TransferMenu() -> Html {
let input = target.and_then(|t| t.dyn_into::<HtmlInputElement>().ok()); let input = target.and_then(|t| t.dyn_into::<HtmlInputElement>().ok());
if let Some(input) = input { if let Some(input) = input {
if input.value() == "" { if input.value() == "" {
return (); return;
} // We do not want empty inputs! } // We do not want empty inputs!
ct_dispatch.reduce_mut(|state| { ct_dispatch.reduce_mut(|state| {
state.transfer.name = input.value().clone(); state.transfer.name = input.value();
}); });
} }
}) })
@ -145,7 +145,6 @@ pub fn TransferMenu() -> Html {
.target() .target()
.expect("Event must have target") .expect("Event must have target")
.dyn_into::<HtmlInputElement>() .dyn_into::<HtmlInputElement>()
.ok()
.expect("Must have been emitted by input"); .expect("Must have been emitted by input");
if let Ok(num) = input.value().parse::<f32>() { if let Ok(num) = input.value().parse::<f32>() {
ct_dispatch.reduce_mut(|state| { ct_dispatch.reduce_mut(|state| {
@ -158,7 +157,6 @@ pub fn TransferMenu() -> Html {
let new_transfer_button_callback = { let new_transfer_button_callback = {
let main_dispatch = main_dispatch.clone(); let main_dispatch = main_dispatch.clone();
let main_state = main_state.clone(); let main_state = main_state.clone();
let ct_dispatch = ct_dispatch.clone();
Callback::from(move |_: MouseEvent| { Callback::from(move |_: MouseEvent| {
main_dispatch.reduce_mut(|state| { main_dispatch.reduce_mut(|state| {
@ -206,41 +204,35 @@ pub fn TransferMenu() -> Html {
}); });
} }
} }
} else { } else if let Some(index) = main_state
if let Some(index) = main_state .transfers
.transfers .iter()
.iter() .position(|t| t.get_uuid() == main_state.selected_transfer)
.position(|t| t.get_uuid() == main_state.selected_transfer) {
{ main_dispatch.reduce_mut(|state| {
main_dispatch.reduce_mut(|state| { state.transfers[index] = ct_state.transfer.clone();
state.transfers[index] = ct_state.transfer.clone(); });
});
}
} }
}) })
}; };
let delete_transfer_button_callback = { let delete_transfer_button_callback = {
let main_dispatch = main_dispatch.clone();
let main_state = main_state.clone();
let ct_state = ct_state.clone(); let ct_state = ct_state.clone();
let new_callback = new_transfer_button_callback.clone(); let new_callback = new_transfer_button_callback.clone();
Callback::from(move |e: MouseEvent| { Callback::from(move |e: MouseEvent| {
if main_state.selected_transfer.is_nil() { if main_state.selected_transfer.is_nil() {
() // Maybe reset transfer? // Maybe reset transfer?
} else { } else if let Some(index) = main_state
if let Some(index) = main_state .transfers
.transfers .iter()
.iter() .position(|t| t.get_uuid() == ct_state.transfer.get_uuid())
.position(|t| t.get_uuid() == ct_state.transfer.get_uuid()) {
{ main_dispatch.reduce_mut(|state| {
main_dispatch.reduce_mut(|state| { state.transfers.remove(index);
state.transfers.remove(index); state.selected_transfer = Uuid::nil();
state.selected_transfer = Uuid::nil(); });
}); new_callback.emit(e); // We need a new transfer now
new_callback.emit(e); // We need a new transfer now
}
} }
}) })
}; };
@ -336,15 +328,15 @@ impl TryFrom<String> for RegionDisplay {
let row_end: u8 = captures[4] let row_end: u8 = captures[4]
.parse::<u8>() .parse::<u8>()
.or(Err("Row end failed to parse"))?; .or(Err("Row end failed to parse"))?;
return Ok(RegionDisplay { Ok(RegionDisplay {
text: value, text: value,
col_start, col_start,
row_start, row_start,
col_end, col_end,
row_end, row_end,
}); })
} else { } else {
return Err("Regex match failed"); Err("Regex match failed")
} }
} }
} }
@ -393,12 +385,12 @@ fn letters_to_num(letters: &str) -> Option<u8> {
let mut num: u8 = 0; let mut num: u8 = 0;
for (i, letter) in letters.chars().rev().enumerate() { for (i, letter) in letters.chars().rev().enumerate() {
let n = letter as u8; let n = letter as u8;
if n < 65 || n > 90 { if !(65..=90).contains(&n) {
return None; return None;
} }
num = num.checked_add((26_i32.pow(i as u32) * (n as i32 - 64)).try_into().ok()?)?; num = num.checked_add((26_i32.pow(i as u32) * (n as i32 - 64)).try_into().ok()?)?;
} }
return Some(num); Some(num)
} }
pub fn num_to_letters(num: u8) -> Option<String> { pub fn num_to_letters(num: u8) -> Option<String> {
if num == 0 { if num == 0 {
@ -418,7 +410,7 @@ pub fn num_to_letters(num: u8) -> Option<String> {
} }
text.push((64 + digit2) as char); text.push((64 + digit2) as char);
return Some(text.to_string()); Some(text.to_string())
} }
#[cfg(test)] #[cfg(test)]

View File

@ -26,7 +26,7 @@ pub fn Tree(props: &TreeProps) -> Html {
let target: Option<EventTarget> = e.target(); let target: Option<EventTarget> = e.target();
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok()); let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
if let Some(li) = li { if let Some(li) = li {
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) { if let Ok(id) = li.id().as_str().parse::<u128>() {
plate_menu_id.set(Some(Uuid::from_u128(id))); plate_menu_id.set(Some(Uuid::from_u128(id)));
} }
} }
@ -57,7 +57,7 @@ pub fn Tree(props: &TreeProps) -> Html {
let target: Option<EventTarget> = e.target(); let target: Option<EventTarget> = e.target();
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok()); let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
if let Some(li) = li { if let Some(li) = li {
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) { if let Ok(id) = li.id().as_str().parse::<u128>() {
ct_dispatch.reduce_mut(|state| { ct_dispatch.reduce_mut(|state| {
state.transfer.transfer_region.source_region = Region::default(); state.transfer.transfer_region.source_region = Region::default();
state.transfer.transfer_region.dest_region = Region::default(); state.transfer.transfer_region.dest_region = Region::default();
@ -78,7 +78,7 @@ pub fn Tree(props: &TreeProps) -> Html {
let target: Option<EventTarget> = e.target(); let target: Option<EventTarget> = e.target();
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok()); let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
if let Some(li) = li { if let Some(li) = li {
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) { if let Ok(id) = li.id().as_str().parse::<u128>() {
ct_dispatch.reduce_mut(|state| { ct_dispatch.reduce_mut(|state| {
state.transfer.transfer_region.source_region = Region::default(); state.transfer.transfer_region.source_region = Region::default();
state.transfer.transfer_region.dest_region = Region::default(); state.transfer.transfer_region.dest_region = Region::default();
@ -94,14 +94,12 @@ pub fn Tree(props: &TreeProps) -> Html {
let transfer_select_callback = { let transfer_select_callback = {
let main_state = main_state.clone(); let main_state = main_state.clone();
let main_dispatch = main_dispatch.clone();
let ct_dispatch = ct_dispatch.clone();
Callback::from(move |e: MouseEvent| { Callback::from(move |e: MouseEvent| {
let target: Option<EventTarget> = e.target(); let target: Option<EventTarget> = e.target();
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok()); let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
if let Some(li) = li { if let Some(li) = li {
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) { if let Ok(id) = li.id().as_str().parse::<u128>() {
let id = Uuid::from_u128(id); let id = Uuid::from_u128(id);
if let Some(transfer) = main_state if let Some(transfer) = main_state
.transfers .transfers
@ -218,7 +216,7 @@ fn PlateInfoModal(props: &PlateInfoModalProps) -> Html {
.source_plates .source_plates
.iter() .iter()
.find(|spi| spi.get_uuid() == props.id); .find(|spi| spi.get_uuid() == props.id);
if plate == None { if plate.is_none() {
plate = main_state plate = main_state
.destination_plates .destination_plates
.iter() .iter()
@ -234,7 +232,6 @@ fn PlateInfoModal(props: &PlateInfoModalProps) -> Html {
}; };
let rename_onchange = { let rename_onchange = {
let main_dispatch = main_dispatch.clone();
let id = props.id; let id = props.id;
Callback::from(move |e: Event| { Callback::from(move |e: Event| {
log::debug!("Changed name"); log::debug!("Changed name");

View File

@ -68,7 +68,7 @@ fn transfer_to_records(
} }
} }
} }
return records; records
} }
fn records_to_csv(trs: Vec<TransferRecord>) -> Result<String, Box<dyn Error>> { fn records_to_csv(trs: Vec<TransferRecord>) -> Result<String, Box<dyn Error>> {
@ -77,5 +77,5 @@ fn records_to_csv(trs: Vec<TransferRecord>) -> Result<String, Box<dyn Error>> {
wtr.serialize(record)? wtr.serialize(record)?
} }
let data = String::from_utf8(wtr.into_inner()?)?; let data = String::from_utf8(wtr.into_inner()?)?;
return Ok(data); Ok(data)
} }

View File

@ -69,9 +69,9 @@ impl TransferRegion {
wells.push((i, j)) wells.push((i, j))
} }
} }
return wells; wells
} }
Region::Point(p) => return vec![p], Region::Point(p) => vec![p],
} }
} }
@ -90,9 +90,10 @@ impl TransferRegion {
} }
// log::debug!("GDW END."); // log::debug!("GDW END.");
return wells; wells
} }
#[allow(clippy::type_complexity)] // Resolving gives inherent associated type error
pub fn calculate_map(&self) -> Box<dyn Fn((u8, u8)) -> Option<Vec<(u8, u8)>> + '_> { pub fn calculate_map(&self) -> Box<dyn Fn((u8, u8)) -> Option<Vec<(u8, u8)>> + '_> {
// By validating first, we have a stronger guarantee that // By validating first, we have a stronger guarantee that
// this function will not panic. :) // this function will not panic. :)
@ -121,30 +122,30 @@ impl TransferRegion {
// Non-replicate transfers: // Non-replicate transfers:
match self.dest_region { match self.dest_region {
Region::Point((x, y)) => { Region::Point((x, y)) => {
return Box::new(move |(i, j)| { Box::new(move |(i, j)| {
if source_wells.contains(&(i, j)) { if source_wells.contains(&(i, j)) {
// Validity here already checked by self.validate() // Validity here already checked by self.validate()
Some(vec![( Some(vec![(
x + i x + i
.checked_sub(source_ul.0) .checked_sub(source_ul.0)
.expect("Point cannot have been less than UL") .expect("Point cannot have been less than UL")
.checked_div(il_source.0.abs() as u8) .checked_div(il_source.0.unsigned_abs())
.expect("Source interleave cannot be 0") .expect("Source interleave cannot be 0")
.mul(il_dest.0.abs() as u8), .mul(il_dest.0.unsigned_abs()),
y + j y + j
.checked_sub(source_ul.1) .checked_sub(source_ul.1)
.expect("Point cannot have been less than UL") .expect("Point cannot have been less than UL")
.checked_div(il_source.1.abs() as u8) .checked_div(il_source.1.unsigned_abs())
.expect("Source interleave cannot be 0") .expect("Source interleave cannot be 0")
.mul(il_dest.1.abs() as u8), .mul(il_dest.1.unsigned_abs()),
)]) )])
} else { } else {
None None
} }
}); })
} }
Region::Rect(c1, c2) => { Region::Rect(c1, c2) => {
return Box::new(move |(i, j)| { Box::new(move |(i, j)| {
if source_wells.contains(&(i, j)) { if source_wells.contains(&(i, j)) {
let possible_destination_wells = create_dense_rectangle(&c1, &c2); let possible_destination_wells = create_dense_rectangle(&c1, &c2);
let (d_ul, d_br) = standardize_rectangle(&c1, &c2); let (d_ul, d_br) = standardize_rectangle(&c1, &c2);
@ -160,58 +161,60 @@ impl TransferRegion {
); );
let N_s = ( let N_s = (
// Number of used source wells // Number of used source wells
(s_dims.0 + il_source.0.abs() as u8 - 1) (s_dims.0 + il_source.0.unsigned_abs() - 1)
.div_euclid(il_source.0.abs() as u8), .div_euclid(il_source.0.unsigned_abs()),
(s_dims.1 + il_source.1.abs() as u8 - 1) (s_dims.1 + il_source.1.unsigned_abs() - 1)
.div_euclid(il_source.1.abs() as u8), .div_euclid(il_source.1.unsigned_abs()),
); );
let count = ( let count = (
// How many times can we replicate? // How many times can we replicate?
(1..) (1..)
.position(|n| { .position(|n| {
n * N_s.0 * il_dest.0.abs() as u8 - il_dest.0.abs() as u8 + 1 n * N_s.0 * il_dest.0.unsigned_abs() - il_dest.0.unsigned_abs()
+ 1
> d_dims.0 > d_dims.0
}) })
.unwrap() as u8, .unwrap() as u8,
(1..) (1..)
.position(|n| { .position(|n| {
n * N_s.1 * il_dest.1.abs() as u8 - il_dest.1.abs() as u8 + 1 n * N_s.1 * il_dest.1.unsigned_abs() - il_dest.1.unsigned_abs()
+ 1
> d_dims.1 > d_dims.1
}) })
.unwrap() as u8, .unwrap() as u8,
); );
let i = i let i = i
.saturating_sub(s_ul.0) .saturating_sub(s_ul.0)
.saturating_div(il_source.0.abs() as u8); .saturating_div(il_source.0.unsigned_abs());
let j = j let j = j
.saturating_sub(s_ul.1) .saturating_sub(s_ul.1)
.saturating_div(il_source.1.abs() as u8); .saturating_div(il_source.1.unsigned_abs());
Some( Some(
possible_destination_wells possible_destination_wells
.into_iter() .into_iter()
.filter(|(x, _)| { .filter(|(x, _)| {
x.checked_sub(d_ul.0).unwrap() x.checked_sub(d_ul.0).unwrap()
% (N_s.0 * il_dest.0.abs() as u8) // Counter along x % (N_s.0 * il_dest.0.unsigned_abs()) // Counter along x
== ((il_dest.0.abs() as u8 *i)) == (il_dest.0.unsigned_abs() *i)
% (N_s.0 * il_dest.0.abs() as u8) % (N_s.0 * il_dest.0.unsigned_abs())
}) })
.filter(|(_, y)| { .filter(|(_, y)| {
y.checked_sub(d_ul.1).unwrap() y.checked_sub(d_ul.1).unwrap()
% (N_s.1 * il_dest.1.abs() as u8) // Counter along u % (N_s.1 * il_dest.1.unsigned_abs()) // Counter along u
== ((il_dest.1.abs() as u8 *j)) == (il_dest.1.unsigned_abs() *j)
% (N_s.1 * il_dest.1.abs() as u8) % (N_s.1 * il_dest.1.unsigned_abs())
}) })
.filter(|(x, y)| { .filter(|(x, y)| {
// How many times have we replicated? < How many are we allowed // How many times have we replicated? < How many are we allowed
// to replicate? // to replicate?
x.checked_sub(d_ul.0) x.checked_sub(d_ul.0)
.unwrap() .unwrap()
.div_euclid(N_s.0 * il_dest.0.abs() as u8) .div_euclid(N_s.0 * il_dest.0.unsigned_abs())
< count.0 < count.0
&& y.checked_sub(d_ul.1) && y.checked_sub(d_ul.1)
.unwrap() .unwrap()
.div_euclid(N_s.1 * il_dest.1.abs() as u8) .div_euclid(N_s.1 * il_dest.1.unsigned_abs())
< count.1 < count.1
}) })
.collect(), .collect(),
@ -219,7 +222,7 @@ impl TransferRegion {
} else { } else {
None None
} }
}); })
} }
} }
} }
@ -265,7 +268,7 @@ impl TransferRegion {
// Should *not* happen in this function---otherwise // Should *not* happen in this function---otherwise
// we'd get a nasty recursive loop. // we'd get a nasty recursive loop.
return Ok(()); Ok(())
} }
} }
@ -280,7 +283,7 @@ fn create_dense_rectangle(c1: &(u8, u8), c2: &(u8, u8)) -> Vec<(u8, u8)> {
} }
} }
return points; points
} }
fn standardize_rectangle(c1: &(u8, u8), c2: &(u8, u8)) -> ((u8, u8), (u8, u8)) { fn standardize_rectangle(c1: &(u8, u8), c2: &(u8, u8)) -> ((u8, u8), (u8, u8)) {
@ -288,10 +291,10 @@ fn standardize_rectangle(c1: &(u8, u8), c2: &(u8, u8)) -> ((u8, u8), (u8, u8)) {
let upper_left_j = u8::min(c1.1, c2.1); let upper_left_j = u8::min(c1.1, c2.1);
let bottom_right_i = u8::max(c1.0, c2.0); let bottom_right_i = u8::max(c1.0, c2.0);
let bottom_right_j = u8::max(c1.1, c2.1); let bottom_right_j = u8::max(c1.1, c2.1);
return ( (
(upper_left_i, upper_left_j), (upper_left_i, upper_left_j),
(bottom_right_i, bottom_right_j), (bottom_right_i, bottom_right_j),
); )
} }
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -308,12 +311,12 @@ impl fmt::Display for TransferRegion {
for i in 1..=source_dims.0 { for i in 1..=source_dims.0 {
for j in 1..=source_dims.1 { for j in 1..=source_dims.1 {
if source_wells.contains(&(i, j)) { if source_wells.contains(&(i, j)) {
source_string.push_str("x") source_string.push('x')
} else { } else {
source_string.push_str(".") source_string.push('.')
} }
} }
source_string.push_str("\n"); source_string.push('\n');
} }
write!(f, "{}", source_string)?; write!(f, "{}", source_string)?;
@ -324,12 +327,12 @@ impl fmt::Display for TransferRegion {
for i in 1..=dest_dims.0 { for i in 1..=dest_dims.0 {
for j in 1..=dest_dims.1 { for j in 1..=dest_dims.1 {
if dest_wells.contains(&(i, j)) { if dest_wells.contains(&(i, j)) {
dest_string.push_str("x") dest_string.push('x')
} else { } else {
dest_string.push_str(".") dest_string.push('.')
} }
} }
dest_string.push_str("\n"); dest_string.push('\n');
} }
write!(f, "{}", dest_string) write!(f, "{}", dest_string)
} }

View File

@ -1,5 +1,4 @@
use plate_tool::App; use plate_tool::App;
use wasm_logger;
fn main() { fn main() {
wasm_logger::init(wasm_logger::Config::default()); wasm_logger::init(wasm_logger::Config::default());