1use std::{fmt::Formatter, pin::Pin};
2
3use rdkit_sys::ro_mol_ffi;
4
5pub struct Atom<'a> {
6 ptr: Pin<&'a mut ro_mol_ffi::Atom>,
7}
8pub use rdkit_sys::ro_mol_ffi::HybridizationType;
9
10impl<'a> std::fmt::Display for Atom<'a> {
11 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
12 let symbol = self.symbol();
13 f.write_str(&symbol)
14 }
15}
16
17impl<'a> std::fmt::Debug for Atom<'a> {
18 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
19 let symbol = self.symbol();
20 f.write_str(&symbol)
21 }
22}
23
24impl<'a> Atom<'a> {
25 pub fn from_ptr(ptr: Pin<&'a mut ro_mol_ffi::Atom>) -> Self {
26 Self { ptr }
27 }
28
29 pub fn symbol(&self) -> String {
30 ro_mol_ffi::get_symbol(self.ptr.as_ref())
31 }
32
33 pub fn get_is_aromatic(&self) -> bool {
34 ro_mol_ffi::get_is_aromatic(self.ptr.as_ref())
35 }
36
37 pub fn get_atomic_num(&self) -> i32 {
38 ro_mol_ffi::get_atomic_num(self.ptr.as_ref())
39 }
40
41 pub fn get_formal_charge(&self) -> i32 {
42 ro_mol_ffi::get_formal_charge(self.ptr.as_ref())
43 }
44
45 pub fn get_total_num_hs(&self) -> u32 {
46 ro_mol_ffi::get_total_num_hs(self.ptr.as_ref())
47 }
48
49 pub fn get_total_valence(&self) -> u32 {
50 ro_mol_ffi::get_total_valence(self.ptr.as_ref())
51 }
52
53 pub fn set_formal_charge(&mut self, what: i32) {
54 ro_mol_ffi::set_formal_charge(self.ptr.as_mut(), what)
55 }
56
57 pub fn set_num_explicit_hs(&mut self, what: i32) {
58 ro_mol_ffi::set_num_explicit_hs(self.ptr.as_mut(), what)
59 }
60
61 pub fn update_property_cache(&mut self, strict: bool) -> Result<(), cxx::Exception> {
62 ro_mol_ffi::atom_update_property_cache(self.ptr.as_mut(), strict)
63 }
64
65 pub fn set_hybridization_type(&mut self, what: HybridizationType) {
66 ro_mol_ffi::atom_set_hybridization(self.ptr.as_mut(), what);
67 }
68
69 pub fn get_hybridization_type(&self) -> HybridizationType {
71 ro_mol_ffi::atom_get_hybridization(self.ptr.as_ref())
72 }
73
74 pub fn set_prop<T>(&mut self, key: &str, value: T)
79 where
80 T: SetPropValue,
81 {
82 value.set_prop(self.ptr.as_mut(), key);
83 }
84
85 pub fn get_int_prop(&self, key: &str) -> Result<i32, cxx::Exception> {
86 cxx::let_cxx_string!(key = key);
87 ro_mol_ffi::get_int_prop(self.ptr.as_ref(), &key)
88 }
89
90 pub fn get_float_prop(&self, key: &str) -> Result<f64, cxx::Exception> {
91 cxx::let_cxx_string!(key = key);
92 ro_mol_ffi::get_float_prop(self.ptr.as_ref(), &key)
93 }
94
95 pub fn get_bool_prop(&self, key: &str) -> Result<bool, cxx::Exception> {
96 cxx::let_cxx_string!(key = key);
97 ro_mol_ffi::get_bool_prop(self.ptr.as_ref(), &key)
98 }
99
100 pub fn get_prop(&self, key: &str) -> Result<String, cxx::Exception> {
101 cxx::let_cxx_string!(key = key);
102 ro_mol_ffi::get_prop(self.ptr.as_ref(), &key)
103 }
104
105 pub fn get_num_radical_electrons(&self) -> u32 {
107 ro_mol_ffi::get_num_radical_electrons(self.ptr.as_ref())
108 }
109
110 pub fn get_degree(&self) -> u32 {
116 ro_mol_ffi::get_degree(self.ptr.as_ref())
117 }
118}
119
120pub trait SetPropValue {
121 fn set_prop(self, ptr: Pin<&mut ro_mol_ffi::Atom>, key: &str);
122}
123
124impl SetPropValue for i32 {
125 fn set_prop(self, ptr: Pin<&mut ro_mol_ffi::Atom>, key: &str) {
126 cxx::let_cxx_string!(key = key);
127 ro_mol_ffi::set_int_prop(ptr, &key, self);
128 }
129}
130
131impl SetPropValue for f64 {
132 fn set_prop(self, ptr: Pin<&mut ro_mol_ffi::Atom>, key: &str) {
133 cxx::let_cxx_string!(key = key);
134 ro_mol_ffi::set_float_prop(ptr, &key, self);
135 }
136}
137
138impl SetPropValue for bool {
139 fn set_prop(self, ptr: Pin<&mut ro_mol_ffi::Atom>, key: &str) {
140 cxx::let_cxx_string!(key = key);
141 ro_mol_ffi::set_bool_prop(ptr, &key, self);
142 }
143}
144
145impl SetPropValue for &str {
146 fn set_prop(self, ptr: Pin<&mut ro_mol_ffi::Atom>, key: &str) {
147 cxx::let_cxx_string!(key = key);
148 cxx::let_cxx_string!(value = self);
149 ro_mol_ffi::set_prop(ptr, &key, &value);
150 }
151}