use std::fmt;
use std::hash::{Hash, Hasher};
#[derive(Clone, PartialEq, Debug, Default)]
#[non_exhaustive]
pub enum AssemblyChoice {
#[default]
AsymmetricUnit,
Biological(Box<str>),
Crystal {
radius: f32,
},
}
impl Hash for AssemblyChoice {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Self::AsymmetricUnit => 0u8.hash(state),
Self::Biological(id) => {
1u8.hash(state);
id.hash(state);
}
Self::Crystal { radius } => {
2u8.hash(state);
radius.to_bits().hash(state);
}
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum ModelChoice {
#[default]
First,
Index(u32),
All,
Ensemble,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum AltlocPolicy {
KeepAll,
#[default]
ConformerConsistent,
Label(Box<str>),
First,
HighestOccupancyPerResidue,
HighestOccupancyPerAtom,
}
impl AltlocPolicy {
#[must_use]
pub const fn is_hazardous(&self) -> bool {
matches!(self, Self::HighestOccupancyPerAtom)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum Namespace {
Label,
#[default]
Auth,
Explicit,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum MissingPolicy {
Ignore,
#[default]
Report,
Indeterminate,
Fail,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum HydrogenPolicy {
#[default]
ExplicitOnly,
IncludeInferred,
Exclude,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum EquivalencePolicy {
None,
#[default]
Ccd,
Explicit,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum SymmetryPolicy {
#[default]
None,
Crystallographic,
BiologicalAssembly,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum AlignmentPolicy {
#[default]
None,
Explicit(Box<str>),
Global,
Local,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum Precision {
F32,
#[default]
F64,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum PeriodicPolicy {
#[default]
None,
Pbc,
MinimumImage,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[non_exhaustive]
pub enum RadiiSet {
#[default]
Bondi,
AmberUnited,
Charmm,
Alvarez,
}
#[derive(Clone, Copy, PartialEq, Debug)]
#[non_exhaustive]
pub enum ContactDefinition {
DistanceCutoff {
tolerance: f32,
},
SurfaceBased {
probe: f32,
},
}
impl Default for ContactDefinition {
fn default() -> Self {
Self::DistanceCutoff { tolerance: 0.5 }
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct Tolerance {
pub relative: f64,
pub absolute: f64,
}
impl Default for Tolerance {
fn default() -> Self {
Self {
relative: 1e-9,
absolute: 1e-12,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct ProfileId(&'static str);
impl ProfileId {
pub const DEFAULT: Self = Self("molframe-default-1.0");
#[must_use]
pub const fn as_str(self) -> &'static str {
self.0
}
}
impl fmt::Display for ProfileId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
#[non_exhaustive]
pub enum PolicyField {
Assembly,
Model,
Altloc,
Identifiers,
MissingAtoms,
Hydrogens,
AtomEquivalence,
Symmetry,
Alignment,
Precision,
Periodic,
VdwRadii,
ContactDef,
FloatTolerance,
}
impl PolicyField {
pub const ALL: [Self; 14] = [
Self::Assembly,
Self::Model,
Self::Altloc,
Self::Identifiers,
Self::MissingAtoms,
Self::Hydrogens,
Self::AtomEquivalence,
Self::Symmetry,
Self::Alignment,
Self::Precision,
Self::Periodic,
Self::VdwRadii,
Self::ContactDef,
Self::FloatTolerance,
];
#[must_use]
pub fn from_name(name: &str) -> Option<Self> {
Self::ALL.into_iter().find(|field| field.name() == name)
}
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Assembly => "assembly",
Self::Model => "model",
Self::Altloc => "altloc",
Self::Identifiers => "identifiers",
Self::MissingAtoms => "missing_atoms",
Self::Hydrogens => "hydrogens",
Self::AtomEquivalence => "atom_equivalence",
Self::Symmetry => "symmetry",
Self::Alignment => "alignment",
Self::Precision => "precision",
Self::Periodic => "periodic",
Self::VdwRadii => "vdw_radii",
Self::ContactDef => "contact_def",
Self::FloatTolerance => "float_tolerance",
}
}
}