1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//! A high-performance Rust library for DREIDING force field atom typing
//! and molecular topology perception.
//!
//! # DreidTyper
//!
//! **DreidTyper** is a foundational software library for the automated assignment
//! of DREIDING force field atom types and the perception of molecular topologies.
//! It provides a modern, robust solution for translating simple chemical connectivity
//! (a `MolecularGraph`) into a complete, engine-agnostic topological description
//! (`MolecularTopology`) essential for molecular simulations.
//!
//! The core mission of DreidTyper is to provide a reliable, predictable, and
//! easy-to-integrate tool for developers and researchers building the next
//! generation of simulation tools for general chemistry, materials science,
//! and drug discovery.
//!
//! # Quickstart
//!
//! The primary entry point of the library is the [`assign_topology`] function.
//! Here's how to build a simple ethanol molecule and perceive its topology:
//!
//! ```
//! use dreid_typer::{
//! assign_topology, MolecularGraph, MolecularTopology,
//! Element, BondOrder,
//! };
//!
//! // 1. Define the molecule's connectivity using a `MolecularGraph`.
//! let mut graph = MolecularGraph::new();
//! let c1 = graph.add_atom(Element::C); // CH3
//! let c2 = graph.add_atom(Element::C); // CH2
//! let o = graph.add_atom(Element::O);
//! let h_c1_1 = graph.add_atom(Element::H);
//! let h_c1_2 = graph.add_atom(Element::H);
//! let h_c1_3 = graph.add_atom(Element::H);
//! let h_c2_1 = graph.add_atom(Element::H);
//! let h_c2_2 = graph.add_atom(Element::H);
//! let h_o = graph.add_atom(Element::H);
//!
//! graph.add_bond(c1, c2, BondOrder::Single).unwrap();
//! graph.add_bond(c2, o, BondOrder::Single).unwrap();
//! graph.add_bond(c1, h_c1_1, BondOrder::Single).unwrap();
//! graph.add_bond(c1, h_c1_2, BondOrder::Single).unwrap();
//! graph.add_bond(c1, h_c1_3, BondOrder::Single).unwrap();
//! graph.add_bond(c2, h_c2_1, BondOrder::Single).unwrap();
//! graph.add_bond(c2, h_c2_2, BondOrder::Single).unwrap();
//! graph.add_bond(o, h_o, BondOrder::Single).unwrap();
//!
//! // 2. Call the main function to perceive the topology.
//! let topology: MolecularTopology = assign_topology(&graph).unwrap();
//!
//! // 3. Inspect the results.
//! assert_eq!(topology.atoms.len(), 9);
//! assert_eq!(topology.bonds.len(), 8);
//! assert_eq!(topology.angles.len(), 13);
//! assert_eq!(topology.proper_dihedrals.len(), 12);
//!
//! // Check the assigned DREIDING atom types.
//! assert_eq!(topology.atoms[c1].atom_type, "C_3"); // sp3 Carbon
//! assert_eq!(topology.atoms[c2].atom_type, "C_3"); // sp3 Carbon
//! assert_eq!(topology.atoms[o].atom_type, "O_3"); // sp3 Oxygen
//! assert_eq!(topology.atoms[h_o].atom_type, "H_HB"); // Hydrogen-bonding Hydrogen
//! assert_eq!(topology.atoms[h_c1_1].atom_type, "H_"); // Standard Hydrogen
//! ```
// Internal modules responsible for the pipeline stages.
// Re-export core data structures for convenient access at the crate root.
pub use crate;
pub use crate;
// Re-export error types for comprehensive error handling.
pub use crate;
/// Provides functionality for parsing and managing DREIDING atom typing rules.
///
/// While the library can be used out-of-the-box with its default ruleset,
/// this module allows advanced users to define and load custom rules from
/// TOML-formatted strings using the [`rules::parse_rules`] function.
/// Assigns a full molecular topology using the default embedded DREIDING ruleset.
///
/// This is the primary, high-level entry point for the library. It orchestrates the
/// entire three-phase pipeline: chemical perception, atom typing, and topology
/// construction. It takes a [`MolecularGraph`] representing the chemical
/// connectivity and returns a complete [`MolecularTopology`] ready for use in
/// molecular simulations.
///
/// # Arguments
///
/// * `graph` - A reference to the [`MolecularGraph`] to be processed.
///
/// # Returns
///
/// A `Result` containing the fully perceived [`MolecularTopology`] on success.
///
/// # Errors
///
/// Returns a [`TyperError`] if any stage of the process fails. This can include:
/// * [`GraphValidationError`] if the input graph is inconsistent (e.g., dangling bonds).
/// * [`AnnotationError`] if the chemical perception logic fails (e.g., cannot determine hybridization).
/// * [`AssignmentError`] if the rule engine cannot assign a type to one or more atoms.
///
/// # Examples
///
/// See the [crate-level documentation](crate) for a detailed example.
/// Assigns a full molecular topology using a user-provided set of rules.
///
/// This function provides the same functionality as [`assign_topology`] but allows
/// for customization of the atom typing logic by supplying a custom slice of [`rules::Rule`]s.
/// This is useful for extending the DREIDING force field to new elements or
/// defining special types for specific chemical environments.
///
/// # Arguments
///
/// * `graph` - A reference to the [`MolecularGraph`] to be processed.
/// * `rules` - A slice of [`rules::Rule`] structs that the typing engine will use.
///
/// # Errors
///
/// Returns a [`TyperError`] under the same conditions as [`assign_topology`].
///
/// # Examples
///
/// ```
/// use dreid_typer::{
/// assign_topology_with_rules, rules, MolecularGraph, Element, BondOrder
/// };
///
/// // Define a simple molecule: a single Carbon atom.
/// let mut graph = MolecularGraph::new();
/// let c = graph.add_atom(Element::C);
///
/// // Define a custom, high-priority rule for a lone carbon atom.
/// let custom_rules_toml = r#"
/// [[rule]]
/// name = "Lone_Carbon"
/// priority = 1000
/// type = "C_LONE"
/// conditions = { element = "C", degree = 0 }
/// "#;
///
/// let my_rules = rules::parse_rules(custom_rules_toml).unwrap();
///
/// // Assign topology using the custom rules.
/// let topology = assign_topology_with_rules(&graph, &my_rules).unwrap();
///
/// assert_eq!(topology.atoms[c].atom_type, "C_LONE");
/// ```
/// Internal core function that executes the perception and typing pipeline.
///
/// This function is the shared implementation for both public-facing `assign_topology`
/// functions. It encapsulates the three-phase process:
/// 1. Perceive chemical properties to create a `ProcessingGraph`.
/// 2. Assign atom types using the provided ruleset.
/// 3. Build the final `MolecularTopology`.