use core::str::FromStr;
use elements_rs::Isotope;
use crate::{
ChargeLike, ChemicalFormula, CountLike, InChIFormula, MineralFormula, ResidualFormula,
errors::ParserError, parsable::MoleculeParser,
};
impl<Count: CountLike> FromStr for InChIFormula<Count> {
type Err = ParserError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
impl<Count: CountLike, Charge: ChargeLike> TryFrom<&str> for ChemicalFormula<Count, Charge>
where
Isotope: TryFrom<(elements_rs::Element, Count), Error = elements_rs::errors::Error>,
Charge: TryFrom<Count>,
{
type Error = ParserError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
impl<Count: CountLike, Charge: ChargeLike> FromStr for ChemicalFormula<Count, Charge>
where
Isotope: TryFrom<(elements_rs::Element, Count), Error = elements_rs::errors::Error>,
Charge: TryFrom<Count>,
{
type Err = ParserError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
impl<Count: CountLike, Charge: ChargeLike> TryFrom<&str> for MineralFormula<Count, Charge>
where
Isotope: TryFrom<(elements_rs::Element, Count), Error = elements_rs::errors::Error>,
Charge: TryFrom<Count>,
{
type Error = ParserError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
impl<Count: CountLike, Charge: ChargeLike> FromStr for MineralFormula<Count, Charge>
where
Isotope: TryFrom<(elements_rs::Element, Count), Error = elements_rs::errors::Error>,
Charge: TryFrom<Count>,
{
type Err = ParserError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
impl<Count: CountLike, Charge: ChargeLike> TryFrom<&str> for ResidualFormula<Count, Charge>
where
Isotope: TryFrom<(elements_rs::Element, Count), Error = elements_rs::errors::Error>,
Charge: TryFrom<Count>,
{
type Error = ParserError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
impl<Count: CountLike, Charge: ChargeLike> FromStr for ResidualFormula<Count, Charge>
where
Isotope: TryFrom<(elements_rs::Element, Count), Error = elements_rs::errors::Error>,
Charge: TryFrom<Count>,
{
type Err = ParserError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
MoleculeParser::new(s.chars())?.parse_formula()
}
}
#[cfg(test)]
mod tests {
use alloc::string::ToString;
use super::*;
#[test]
fn test_inchi_formula_from_str() {
let input = "C2H5";
let expected = "C2H5"; let formula = InChIFormula::<u32>::from_str(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
#[test]
fn test_chemical_formula_try_from() {
let input = "H2O";
let expected = "H₂O"; let formula = ChemicalFormula::<u32, i32>::try_from(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
#[test]
fn test_chemical_formula_from_str() {
let input = "H2O";
let expected = "H₂O";
let formula = ChemicalFormula::<u32, i32>::from_str(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
#[test]
fn test_mineral_formula_try_from() {
let input = "SiO2";
let expected = "SiO₂"; let formula = MineralFormula::<u32, i32>::try_from(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
#[test]
fn test_mineral_formula_from_str() {
let input = "SiO2";
let expected = "SiO₂";
let formula = MineralFormula::<u32, i32>::from_str(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
#[test]
fn test_residual_formula_try_from() {
let input = "C6H12O6";
let expected = "C₆H₁₂O₆"; let formula = ResidualFormula::<u32, i32>::try_from(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
#[test]
fn test_residual_formula_from_str() {
let input = "C6H12O6";
let expected = "C₆H₁₂O₆";
let formula = ResidualFormula::<u32, i32>::from_str(input).unwrap();
assert_eq!(formula.to_string(), expected);
}
}