use crate::error::Result;
use std::os::raw::c_int;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum InchiValidity {
Standard,
NonStandard,
Beta,
InvalidPrefix,
InvalidVersion,
InvalidLayout,
FailedRoundtrip,
Other(i32),
}
impl InchiValidity {
#[must_use]
pub fn is_valid(self) -> bool {
matches!(self, InchiValidity::Standard | InchiValidity::NonStandard | InchiValidity::Beta)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum InchiKeyValidity {
Standard,
NonStandard,
InvalidLength,
InvalidLayout,
InvalidVersion,
Other(i32),
}
impl InchiKeyValidity {
#[must_use]
pub fn is_valid(self) -> bool {
matches!(self, InchiKeyValidity::Standard | InchiKeyValidity::NonStandard)
}
}
pub fn check_inchi(inchi: impl AsRef<str>, strict: bool) -> Result<InchiValidity> {
let src = crate::raw::to_cstring(inchi.as_ref())?;
let _guard = crate::raw::lock();
let rc = unsafe { inchi_sys::CheckINCHI(src.as_ptr(), c_int::from(strict)) };
drop(src);
Ok(match rc {
x if x == inchi_sys::INCHI_VALID_STANDARD as i32 => InchiValidity::Standard,
x if x == inchi_sys::INCHI_VALID_NON_STANDARD as i32 => InchiValidity::NonStandard,
x if x == inchi_sys::INCHI_VALID_BETA as i32 => InchiValidity::Beta,
x if x == inchi_sys::INCHI_INVALID_PREFIX as i32 => InchiValidity::InvalidPrefix,
x if x == inchi_sys::INCHI_INVALID_VERSION as i32 => InchiValidity::InvalidVersion,
x if x == inchi_sys::INCHI_INVALID_LAYOUT as i32 => InchiValidity::InvalidLayout,
x if x == inchi_sys::INCHI_FAIL_I2I as i32 => InchiValidity::FailedRoundtrip,
other => InchiValidity::Other(other),
})
}
pub fn check_inchikey(key: impl AsRef<str>) -> Result<InchiKeyValidity> {
let src = crate::raw::to_cstring(key.as_ref())?;
let _guard = crate::raw::lock();
let rc = unsafe { inchi_sys::CheckINCHIKey(src.as_ptr()) };
drop(src);
Ok(match rc {
x if x == inchi_sys::INCHIKEY_VALID_STANDARD => InchiKeyValidity::Standard,
x if x == inchi_sys::INCHIKEY_VALID_NON_STANDARD => InchiKeyValidity::NonStandard,
x if x == inchi_sys::INCHIKEY_INVALID_LENGTH => InchiKeyValidity::InvalidLength,
x if x == inchi_sys::INCHIKEY_INVALID_LAYOUT => InchiKeyValidity::InvalidLayout,
x if x == inchi_sys::INCHIKEY_INVALID_VERSION => InchiKeyValidity::InvalidVersion,
other => InchiKeyValidity::Other(other),
})
}