refactor: sort all from_str-like impls together

This commit is contained in:
electria 2026-07-16 00:02:05 -07:00
commit b9fc3c1eec
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs
2 changed files with 41 additions and 52 deletions

View file

@ -2,7 +2,7 @@ use std::str::FromStr;
use rug::{Float, float::ParseFloatError, ops::CompleteRound};
use crate::nodes::{Node, Nodes, PREC};
use crate::nodes::{Function, Node, Nodes, Operator, PREC};
#[derive(Clone, Debug, thiserror::Error)]
pub enum Error {
@ -14,6 +14,45 @@ pub enum Error {
NumberParsing(String, ParseFloatError),
}
impl Node {
fn from_name(s: &str) -> Result<Self, Error> {
Ok(match s {
"c" => Self::Number(Float::with_val(PREC, 299_792_458)),
"A" => Self::Number(Float::with_val(PREC, 6.02214076e23)),
_ => Self::Function(s.parse()?),
})
}
}
impl TryFrom<char> for Operator {
type Error = ();
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
'+' => Ok(Self::Plus),
'-' => Ok(Self::Minus),
'*' => Ok(Self::Mult),
'/' => Ok(Self::Div),
'^' => Ok(Self::Exp),
_ => Err(()),
}
}
}
impl FromStr for Function {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"sin" => Ok(Self::Sine),
"asin" => Ok(Self::ArcSine),
"cos" => Ok(Self::Cosine),
"acos" => Ok(Self::ArcCosine),
"tan" => Ok(Self::Tangent),
"atan" => Ok(Self::ArcTangent),
"sec" => Ok(Self::Secant),
"csc" => Ok(Self::CoSecant),
_ => Err(Error::UnrecognizedName(s.to_owned())),
}
}
}
#[derive(Clone, Debug, Default, PartialEq)]
enum ParsingState {
#[default]
@ -21,17 +60,6 @@ enum ParsingState {
ReadingFunctionName(usize),
ReadingNumber(usize),
}
impl Node {
fn from_name(s: &str) -> Result<Self, ()> {
Ok(match s {
"c" => Self::Number(Float::with_val(PREC, 299_792_458)),
"A" => Self::Number(Float::with_val(PREC, 6.02214076e23)),
f => Self::Function(f.parse()?),
})
}
}
impl FromStr for Nodes {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -66,11 +94,7 @@ impl FromStr for Nodes {
ParsingState::Start => {}
ParsingState::ReadingFunctionName(start_index) => {
if !c.is_alphabetic() {
nodes.push(Node::from_name(&filtered_string[start_index..i]).map_err(
|()| {
Error::UnrecognizedName(filtered_string[start_index..i].to_owned())
},
)?);
nodes.push(Node::from_name(&filtered_string[start_index..i])?);
state = ParsingState::Start;
}
@ -120,11 +144,7 @@ impl FromStr for Nodes {
match state {
ParsingState::Start => {}
ParsingState::ReadingFunctionName(start_index) => {
nodes.push(
Node::from_name(&filtered_string[start_index..i]).map_err(|()| {
Error::UnrecognizedName(filtered_string[start_index..i].to_owned())
})?,
);
nodes.push(Node::from_name(&filtered_string[start_index..i])?);
}
ParsingState::ReadingNumber(start_index) => {
nodes.push(Node::Number(

View file

@ -2,8 +2,6 @@
//! as well as the logic to parse it from a string (`Node::from_str`),
//! and the logic to evaluate it into a single number (`Node::evaluate`).
use std::str::FromStr;
use rug::Float;
mod evaluate;
@ -38,19 +36,6 @@ enum Operator {
Div,
Exp,
}
impl TryFrom<char> for Operator {
type Error = ();
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
'+' => Ok(Self::Plus),
'-' => Ok(Self::Minus),
'*' => Ok(Self::Mult),
'/' => Ok(Self::Div),
'^' => Ok(Self::Exp),
_ => Err(()),
}
}
}
#[derive(Clone, Debug, PartialEq)]
enum Function {
@ -63,19 +48,3 @@ enum Function {
Secant,
CoSecant,
}
impl FromStr for Function {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"sin" => Ok(Self::Sine),
"asin" => Ok(Self::ArcSine),
"cos" => Ok(Self::Cosine),
"acos" => Ok(Self::ArcCosine),
"tan" => Ok(Self::Tangent),
"atan" => Ok(Self::ArcTangent),
"sec" => Ok(Self::Secant),
"csc" => Ok(Self::CoSecant),
_ => Err(()),
}
}
}