Skip to content

Commit

Permalink
Add more macros (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
pumken authored Mar 22, 2023
1 parent ccd98a8 commit f3474c7
Show file tree
Hide file tree
Showing 13 changed files with 392 additions and 145 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "chemcreator"
version = "1.2.0"
version = "1.2.1"
description = "A text-based tool for identifying organic molecules."
authors = ["Gavin Tran"]
readme = "README.md"
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ you try it out and find something named incorrectly, please open an issue!
- [x] Alkenes
- [x] Alkynes
- [x] Alcohols
- [ ] Aldehydes
- [x] Aldehydes
- [x] Amides
- [x] Amines
- [x] Carboxylic acids
- [ ] Ethers
- [x] Ketones
- [ ] Halogenoalkanes
- [x] Halogenoalkanes
- [ ] Esters
19 changes: 9 additions & 10 deletions src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ mod tests {
use crate::graph_with;
use crate::molecule::BondOrder::Single;
use crate::molecule::Element::{C, H};
use crate::test_utils::unwrap_atom;
use crate::test_utils::GW::{A, B};

// Also checks accumulate_carbons
Expand All @@ -226,7 +225,7 @@ mod tests {
[1, 0; A(C)],
[2, 0; A(C)], [2, 1; A(C)], [2, 2; A(C)],
[3, 0; A(C)],
[4, 0; A(C)]
[4, 0; A(C)],
);
let accumulator = endpoint_head_chains(
Atom {
Expand All @@ -251,7 +250,7 @@ mod tests {
[1, 0; A(C)],
[2, 0; A(C)], [2, 1; A(C)], [2, 2; A(C)],
[3, 0; A(C)],
[4, 0; A(C)]
[4, 0; A(C)],
);
let accumulator = endpoint_head_chains(
Atom {
Expand Down Expand Up @@ -302,15 +301,15 @@ mod tests {
[1, 0; A(H)],
[1, 1; A(C)],
[1, 2; A(C)],
[2, 1; A(C)]
[2, 1; A(C)],
);
let atoms = next_carbons(Vec2::xy(1, 1), None, &graph).unwrap();
let expected = vec![
graph.get(Vec2::xy(1, 2)).unwrap(),
graph.get(Vec2::xy(2, 1)).unwrap(),
]
.iter()
.map(|&cell| unwrap_atom(cell))
.map(|&cell| cell.unwrap_atom())
.collect::<Vec<Atom>>();

assert_eq!(atoms, expected);
Expand All @@ -323,10 +322,10 @@ mod tests {
[1, 0; A(H)],
[1, 1; A(C)],
[1, 2; A(C)],
[2, 1; A(C)]
[2, 1; A(C)],
);
let atom = next_carbons(Vec2::xy(1, 1), Some(Vec2::xy(1, 2)), &graph).unwrap();
let expected = vec![unwrap_atom(graph.get(Vec2::xy(2, 1)).unwrap())];
let expected = vec![graph.get(Vec2::xy(2, 1)).unwrap().unwrap_atom()];

assert_eq!(atom, expected);
}
Expand All @@ -340,7 +339,7 @@ mod tests {
[3, 0; A(H)], [3, 1; A(C)], [3, 2; A(H)],
[4, 1; B(Single)],
[5, 0; A(H)], [5, 1; A(C)], [5, 2; A(H)],
[6, 1; A(H)]
[6, 1; A(H)],
);
let cells = endpoint_carbons(&graph).unwrap();
let expected = vec![
Expand All @@ -356,7 +355,7 @@ mod tests {
let graph = graph_with!(3, 3,
[0, 1; A(H)],
[1, 0; A(H)], [1, 1; A(C)], [1, 2; A(H)],
[2, 1; A(H)]
[2, 1; A(H)],
);
let cell = endpoint_carbons(&graph).unwrap();
let expected = vec![graph.get(Vec2::xy(1, 1)).unwrap()];
Expand All @@ -370,7 +369,7 @@ mod tests {
[0, 0; A(C)],
[1, 0; A(C)],
[2, 0; A(C)],
[0, 2; A(C)]
[0, 2; A(C)],
);
let network = get_connected_cells(Vec2::xy(0, 0), &graph).unwrap();
let expected = vec![
Expand Down
23 changes: 12 additions & 11 deletions src/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::chain::{endpoint_head_chains, longest_chain};
use crate::compound;
use crate::groups::InvalidGraphError::{Other, UnrecognizedGroup};
use crate::molecule::Group::{
AcidHalide, Aldehyde, Alkene, Alkyne, Amine, Bromo, Carbonyl, Carboxyl, Chloro, Fluoro,
AcidHalide, Aldehyde, Alkene, Alkyne, Amide, Amine, Bromo, Carbonyl, Carboxyl, Chloro, Fluoro,
Hydrogen, Hydroxyl, Iodo, Nitrile,
};
use crate::molecule::Halogen::{Bromine, Chlorine, Fluorine, Iodine};
Expand Down Expand Up @@ -131,7 +131,8 @@ fn group_patterns(mut groups: Vec<Group>) -> Vec<Substituent> {
[Carbonyl, Chloro => AcidHalide(Chlorine)],
[Carbonyl, Bromo => AcidHalide(Bromine)],
[Carbonyl, Iodo => AcidHalide(Iodine)],
[Carbonyl, Hydrogen => Aldehyde]
[Carbonyl, Amine => Amide],
[Carbonyl, Hydrogen => Aldehyde],
);
groups.retain(|it| it != &Hydrogen);
break;
Expand All @@ -150,7 +151,7 @@ fn group_patterns(mut groups: Vec<Group>) -> Vec<Substituent> {
/// groups to `out`.
#[macro_export]
macro_rules! compound {
($groups:expr, $out:expr, $([$first:expr, $second:expr => $comp:expr]),*) => {
($groups:expr, $out:expr, $([$first:expr, $second:expr => $comp:expr],)*) => {
$(
if $groups.contains(&$first) && $groups.contains(&$second) {
$groups.retain(|it| it != &$first && it != &$second);
Expand Down Expand Up @@ -323,7 +324,7 @@ mod tests {
[2, 1; B(Single)],
[3, 0; A(H)], [3, 1; A(C)], [3, 2; A(H)],
[4, 1; A(O)],
[5, 1; A(H)]
[5, 1; A(H)],
);
let chain = vec![
Atom {
Expand Down Expand Up @@ -399,7 +400,7 @@ mod tests {
[0, 1; B(Single)],
[0, 2; A(O)],
[0, 3; B(Single)],
[0, 4; A(H)]
[0, 4; A(H)],
);
let a = group_node_tree(&graph, Vec2::xy(0, 0), Direction::Up).unwrap();
let b = GroupNode {
Expand All @@ -420,7 +421,7 @@ mod tests {
let graph = graph_with!(1, 3,
[0, 0; A(C)],
[0, 1; A(O)],
[0, 2; A(H)]
[0, 2; A(H)],
);
let node = group_node_tree(&graph, Vec2::xy(0, 0), Direction::Up).unwrap();
let expected = GroupNode {
Expand All @@ -441,7 +442,7 @@ mod tests {
let graph = graph_with!(3, 3,
[0, 0; A(H)], [0, 1; A(C)], [0, 2; A(H)],
[1, 1; B(Double)],
[2, 0; A(H)], [2, 1; A(C)], [2, 2; A(H)]
[2, 0; A(H)], [2, 1; A(C)], [2, 2; A(H)],
);
let node = group_node_tree(&graph, Vec2::xy(0, 1), Direction::Right).unwrap();
let expected = GroupNode {
Expand All @@ -458,7 +459,7 @@ mod tests {
let graph = graph_with!(3, 3,
[0, 1; A(C)],
[1, 0; A(H)], [1, 1; A(C)],
[2, 1; A(C)]
[2, 1; A(C)],
);
let directions = next_directions(&graph, Vec2::xy(1, 1), Vec2::xy(0, 1)).unwrap();
let expected = vec![Direction::Down, Direction::Right];
Expand All @@ -472,7 +473,7 @@ mod tests {
[0, 1; A(C)],
[1, 0; A(H)],
[1, 1; A(C)],
[2, 1; A(C)]
[2, 1; A(C)],
);
let directions = next_directions(&graph, Vec2::xy(1, 1), Vec2::xy(0, 1)).unwrap();
let expected = vec![Direction::Down, Direction::Right];
Expand All @@ -485,7 +486,7 @@ mod tests {
let graph = graph_with!(5, 5,
[0, 2; A(C)],
[1, 2; B(Single)],
[2, 0; A(C)], [2, 1; B(Double)], [2, 2; A(C)], [2, 3; A(O)], [2, 4; A(H)]
[2, 0; A(C)], [2, 1; B(Double)], [2, 2; A(C)], [2, 3; A(O)], [2, 4; A(H)],
);
let branch = Branch {
chain: vec![
Expand Down Expand Up @@ -514,7 +515,7 @@ mod tests {
[1, 0; A(Br)],
[1, 1; A(C)],
[1, 2; A(I)],
[2, 1; A(F)]
[2, 1; A(F)],
);
let branch = Branch {
chain: vec![Atom {
Expand Down
58 changes: 29 additions & 29 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,55 @@
use crate::groups::debug_branches;
use crate::macros::invoke_macro;
use crate::molecule::BondOrder::{Double, Single, Triple};
use crate::molecule::Element;
use crate::molecule::Element::{C, H, N, O};
use crate::molecule::Element::{Cl, C, H, I, N, O};
use crate::molecule::{ComponentType, Element};
use crate::naming::name_molecule;
use crate::spatial::GridState;
use crate::{AppState, Mode};
use ruscii::app::State;
use ruscii::keyboard::{Key, KeyEvent};
use ruscii::spatial::Direction;
use Element::{Br, F};

pub(crate) fn input_insert_mode(app_state: &State, state: &mut AppState, graph: &mut GridState) {
for key_event in app_state.keyboard().last_key_events() {
match key_event {
KeyEvent::Pressed(Key::B) => {
graph.put_atom(Element::Br);
state.key = "B";
update(state, graph);
update(state, graph, ComponentType::Element(Br));
}
KeyEvent::Pressed(Key::C) => {
graph.put_atom(C);
state.key = "C";
update(state, graph);
update(state, graph, ComponentType::Element(C));
}
KeyEvent::Pressed(Key::F) => {
graph.put_atom(Element::F);
state.key = "F";
update(state, graph);
update(state, graph, ComponentType::Element(F));
}
KeyEvent::Pressed(Key::H) => {
graph.put_atom(H);
state.key = "H";
update(state, graph);
update(state, graph, ComponentType::Element(H));
}
KeyEvent::Pressed(Key::I) => {
graph.put_atom(Element::I);
state.key = "I";
update(state, graph);
update(state, graph, ComponentType::Element(I));
}
KeyEvent::Pressed(Key::L) => {
graph.put_atom(Element::Cl);
state.key = "L";
update(state, graph);
update(state, graph, ComponentType::Element(Cl));
}
KeyEvent::Pressed(Key::N) => {
graph.put_atom(N);
state.key = "N";
update(state, graph);
update(state, graph, ComponentType::Element(N));
}
KeyEvent::Pressed(Key::O) => {
graph.put_atom(O);
state.key = "O";
update(state, graph);
update(state, graph, ComponentType::Element(O));
}
KeyEvent::Pressed(Key::F5) => {
graph.clear_all();
state.key = "F5";
update(state, graph);
update(state, graph, ComponentType::None);
}
KeyEvent::Pressed(Key::F7) => {
state.macros_enabled = !state.macros_enabled;
Expand All @@ -74,24 +67,20 @@ pub(crate) fn input_insert_mode(app_state: &State, state: &mut AppState, graph:
state.key = "F12";
}
KeyEvent::Pressed(Key::Num1) => {
graph.put_bond(Single);
state.key = "1";
update(state, graph);
update(state, graph, ComponentType::Order(Single));
}
KeyEvent::Pressed(Key::Num2) => {
graph.put_bond(Double);
state.key = "2";
update(state, graph);
update(state, graph, ComponentType::Order(Double));
}
KeyEvent::Pressed(Key::Num3) => {
graph.put_bond(Triple);
state.key = "3";
update(state, graph);
update(state, graph, ComponentType::Order(Triple));
}
KeyEvent::Pressed(Key::Backspace) => {
graph.clear_cell();
state.key = "Backspace";
update(state, graph);
update(state, graph, ComponentType::None);
}
KeyEvent::Pressed(Key::Right) => {
graph.move_cursor(Direction::Right);
Expand Down Expand Up @@ -134,9 +123,20 @@ pub(crate) fn input_view_mode(app_state: &State, state: &mut AppState) {
}

//noinspection RsBorrowChecker
pub(crate) fn update(state: &mut AppState, graph: &mut GridState) {
pub(crate) fn update(state: &mut AppState, graph: &mut GridState, comp: ComponentType) {
let previous = graph
.current_cell()
.expect("cell should be within bounds")
.comp();

match comp {
ComponentType::Element(it) => graph.put_atom(it),
ComponentType::Order(it) => graph.put_bond(it),
ComponentType::None => graph.clear_cell(),
}

if state.macros_enabled {
invoke_macro(graph);
invoke_macro(graph, comp, previous);
}

(state.name, state.err) = match name_molecule(graph) {
Expand Down
Loading

0 comments on commit f3474c7

Please sign in to comment.