diff --git a/Cargo.lock b/Cargo.lock index e921acb..8f9dde5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -565,6 +565,7 @@ dependencies = [ "js-sys", "lazy_static", "log", + "plate-tool-lib", "rand", "regex", "serde", @@ -578,6 +579,20 @@ dependencies = [ "yewdux", ] +[[package]] +name = "plate-tool-lib" +version = "0.1.0" +dependencies = [ + "csv", + "getrandom", + "log", + "rand", + "regex", + "serde", + "serde_json", + "uuid", +] + [[package]] name = "ppv-lite86" version = "0.2.17" diff --git a/Cargo.toml b/Cargo.toml index cc87d26..381c5c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +plate-tool-lib = { path = "lib" } yew = { version = "0.20.0", features = ["csr"] } yewdux = "0.9" wasm-bindgen = "0.2" diff --git a/assets/scss/default_theme/components/_plate_container.scss b/assets/scss/default_theme/components/_plate_container.scss index cff857f..182bc24 100644 --- a/assets/scss/default_theme/components/_plate_container.scss +++ b/assets/scss/default_theme/components/_plate_container.scss @@ -15,4 +15,27 @@ div.plate_container { margin-bottom: 1%; text-align: center; } + + &>div { + display: grid; + grid-template-rows: auto auto; + grid-template-rows: auto auto; + + &>h2:nth-of-type(1) { + grid-column: 2; + grid-row: 1; + } + + &>h2:nth-of-type(2) { + grid-column: 1; + grid-row: 2; + writing-mode: vertical-rl; + transform: rotate(-180deg); + } + + &>div { + grid-column:2; + grid-row: 2; + } + } } diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 0000000..4f96631 --- /dev/null +++ b/lib/.gitignore @@ -0,0 +1,2 @@ +/target +/dist diff --git a/lib/Cargo.lock b/lib/Cargo.lock new file mode 100644 index 0000000..5c974a4 --- /dev/null +++ b/lib/Cargo.lock @@ -0,0 +1,339 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "plate-tool-lib" +version = "0.1.0" +dependencies = [ + "csv", + "getrandom", + "log", + "rand", + "regex", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "uuid" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +dependencies = [ + "atomic", + "getrandom", + "rand", + "serde", + "uuid-macro-internal", + "wasm-bindgen", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abb14ae1a50dad63eaa768a458ef43d298cd1bd44951677bd10b732a9ba2a2d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" diff --git a/lib/Cargo.toml b/lib/Cargo.toml new file mode 100644 index 0000000..c8103a2 --- /dev/null +++ b/lib/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "plate-tool-lib" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +log = "0.4" +regex = "1" +uuid = { version = "1.6", features = ["v7", "fast-rng", "macro-diagnostics", "js", "serde"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +csv = "1.2" +getrandom = { version = "0.2", features = ["js"] } +rand = { version = "0.8", features = ["small_rng"] } diff --git a/src/data/csv.rs b/lib/src/csv.rs similarity index 95% rename from src/data/csv.rs rename to lib/src/csv.rs index c0f03dc..8a4ee25 100644 --- a/src/data/csv.rs +++ b/lib/src/csv.rs @@ -1,6 +1,6 @@ -use crate::components::states::MainState; -use crate::components::transfer_menu::num_to_letters; -use crate::data::transfer::Transfer; +// use crate::components::states::MainState; +use crate::transfer::Transfer; +use crate::util::*; use serde::{Serialize, Deserialize}; use std::error::Error; @@ -21,6 +21,7 @@ pub struct TransferRecord { pub concentration: Option, } +/* pub fn state_to_csv(state: &MainState) -> Result> { let mut records: Vec = Vec::new(); for transfer in &state.transfers { @@ -42,6 +43,7 @@ pub fn state_to_csv(state: &MainState) -> Result> { } records_to_csv(records) } +*/ fn transfer_to_records( tr: &Transfer, diff --git a/src/data/mod.rs b/lib/src/lib.rs similarity index 87% rename from src/data/mod.rs rename to lib/src/lib.rs index bc5afaa..a85a4bb 100644 --- a/src/data/mod.rs +++ b/lib/src/lib.rs @@ -3,3 +3,4 @@ pub mod plate; pub mod plate_instances; pub mod transfer; pub mod transfer_region; +pub mod util; diff --git a/src/data/plate.rs b/lib/src/plate.rs similarity index 100% rename from src/data/plate.rs rename to lib/src/plate.rs diff --git a/src/data/plate_instances.rs b/lib/src/plate_instances.rs similarity index 100% rename from src/data/plate_instances.rs rename to lib/src/plate_instances.rs diff --git a/src/data/transfer.rs b/lib/src/transfer.rs similarity index 100% rename from src/data/transfer.rs rename to lib/src/transfer.rs diff --git a/src/data/transfer_region.rs b/lib/src/transfer_region.rs similarity index 100% rename from src/data/transfer_region.rs rename to lib/src/transfer_region.rs diff --git a/lib/src/util.rs b/lib/src/util.rs new file mode 100644 index 0000000..b8ec34d --- /dev/null +++ b/lib/src/util.rs @@ -0,0 +1,70 @@ +pub fn letters_to_num(letters: &str) -> Option { + let mut num: u8 = 0; + for (i, letter) in letters.to_ascii_uppercase().chars().rev().enumerate() { + log::debug!("{}, {}", i, letter); + let n = letter as u8; + if !(65..=90).contains(&n) { + return None; + } + num = num.checked_add((26_i32.pow(i as u32) * (n as i32 - 64)).try_into().ok()?)?; + } + Some(num) +} +pub fn num_to_letters(num: u8) -> Option { + if num == 0 { + return None; + } // Otherwise, we will not return none! + // As another note, we can't represent higher than "IV" anyway; + // thus there's no reason for a loop (26^n with n>1 will NOT occur). + let mut text = "".to_string(); + let mut digit1 = num.div_euclid(26u8); + let mut digit2 = num.rem_euclid(26u8); + if digit1 > 0 && digit2 == 0u8 { + digit1 -= 1; + digit2 = 26; + } + if digit1 != 0 { + text.push((64 + digit1) as char) + } + text.push((64 + digit2) as char); + + Some(text.to_string()) +} + +#[cfg(test)] +mod tests { + use super::{letters_to_num, num_to_letters, RegionDisplay}; + + #[test] + fn test_letters_to_num() { + assert_eq!(letters_to_num("D"), Some(4)); + assert_eq!(letters_to_num("d"), None); + assert_eq!(letters_to_num("AD"), Some(26 + 4)); + assert_eq!(letters_to_num("CG"), Some(3 * 26 + 7)); + } + + #[test] + fn test_num_to_letters() { + println!("27 is {:?}", num_to_letters(27)); + assert_eq!(num_to_letters(1), Some("A".to_string())); + assert_eq!(num_to_letters(26), Some("Z".to_string())); + assert_eq!(num_to_letters(27), Some("AA".to_string())); + assert_eq!(num_to_letters(111), Some("DG".to_string())); + } + + #[test] + fn test_l2n_and_n2l() { + assert_eq!( + num_to_letters(letters_to_num("A").unwrap()), + Some("A".to_string()) + ); + assert_eq!( + num_to_letters(letters_to_num("BJ").unwrap()), + Some("BJ".to_string()) + ); + for i in 1..=255 { + assert_eq!(letters_to_num(&num_to_letters(i).unwrap()), Some(i)); + } + } + +} diff --git a/src/components/plates/plate_container.rs b/src/components/plates/plate_container.rs index 8746e81..88a50ee 100644 --- a/src/components/plates/plate_container.rs +++ b/src/components/plates/plate_container.rs @@ -55,11 +55,13 @@ pub fn PlateContainer(props: &PlateContainerProps) -> Html { if let Some(dpi) = props.destination_dims.clone() {

{spi.name.clone()}

+

{"Source"}

{dpi.name.clone()}

+

{"Destination"}

diff --git a/src/components/transfer_menu.rs b/src/components/transfer_menu.rs index 3b298c7..125d478 100644 --- a/src/components/transfer_menu.rs +++ b/src/components/transfer_menu.rs @@ -277,80 +277,11 @@ impl TryFrom<(u8, u8, u8, u8)> for RegionDisplay { }) } } -pub fn letters_to_num(letters: &str) -> Option { - let mut num: u8 = 0; - for (i, letter) in letters.to_ascii_uppercase().chars().rev().enumerate() { - log::debug!("{}, {}", i, letter); - let n = letter as u8; - if !(65..=90).contains(&n) { - return None; - } - num = num.checked_add((26_i32.pow(i as u32) * (n as i32 - 64)).try_into().ok()?)?; - } - Some(num) -} -pub fn num_to_letters(num: u8) -> Option { - if num == 0 { - return None; - } // Otherwise, we will not return none! - // As another note, we can't represent higher than "IV" anyway; - // thus there's no reason for a loop (26^n with n>1 will NOT occur). - let mut text = "".to_string(); - let mut digit1 = num.div_euclid(26u8); - let mut digit2 = num.rem_euclid(26u8); - if digit1 > 0 && digit2 == 0u8 { - digit1 -= 1; - digit2 = 26; - } - if digit1 != 0 { - text.push((64 + digit1) as char) - } - text.push((64 + digit2) as char); - - Some(text.to_string()) -} #[cfg(test)] mod tests { use wasm_bindgen_test::*; - use super::{letters_to_num, num_to_letters, RegionDisplay}; - - #[test] - #[wasm_bindgen_test] - fn test_letters_to_num() { - assert_eq!(letters_to_num("D"), Some(4)); - assert_eq!(letters_to_num("d"), None); - assert_eq!(letters_to_num("AD"), Some(26 + 4)); - assert_eq!(letters_to_num("CG"), Some(3 * 26 + 7)); - } - - #[test] - #[wasm_bindgen_test] - fn test_num_to_letters() { - println!("27 is {:?}", num_to_letters(27)); - assert_eq!(num_to_letters(1), Some("A".to_string())); - assert_eq!(num_to_letters(26), Some("Z".to_string())); - assert_eq!(num_to_letters(27), Some("AA".to_string())); - assert_eq!(num_to_letters(111), Some("DG".to_string())); - } - - #[test] - #[wasm_bindgen_test] - fn test_l2n_and_n2l() { - assert_eq!( - num_to_letters(letters_to_num("A").unwrap()), - Some("A".to_string()) - ); - assert_eq!( - num_to_letters(letters_to_num("BJ").unwrap()), - Some("BJ".to_string()) - ); - for i in 1..=255 { - assert_eq!(letters_to_num(&num_to_letters(i).unwrap()), Some(i)); - } - } - #[test] #[wasm_bindgen_test] fn test_try_from_string_for_regiondisplay() {