diff --git a/core/src/ast.rs b/core/src/ast.rs index b3780d30..2c3ca407 100644 --- a/core/src/ast.rs +++ b/core/src/ast.rs @@ -3,8 +3,9 @@ use crate::eval::evaluate_to_value; use crate::ident::Ident; use crate::interrupt::test_int; use crate::num::{Base, FormattingStyle, Number}; +use crate::result::FendCoreResult; use crate::scope::Scope; -use crate::serialize::{deserialize_u8, serialize_u8}; +use crate::serialize::{Deserialize, Serialize}; use crate::value::{built_in_function::BuiltInFunction, ApplyMulHandling, Value}; use crate::Attrs; use std::sync::Arc; @@ -34,8 +35,8 @@ pub(crate) enum Bop { } impl Bop { - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - let n = match self { + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + let n: u8 = match self { Self::Plus => 0, Self::ImplicitPlus => 1, Self::Minus => 2, @@ -51,12 +52,12 @@ impl Bop { Self::Combination => 12, Self::Permutation => 13, }; - serialize_u8(n, write)?; + n.serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(match u8::deserialize(read)? { 0 => Self::Plus, 1 => Self::ImplicitPlus, 2 => Self::Minus, @@ -125,79 +126,79 @@ pub(crate) enum Expr { } impl Expr { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { match self { Self::Literal(x) => { - serialize_u8(0, write)?; + 0u8.serialize(write)?; x.serialize(write)?; } Self::Ident(i) => { - serialize_u8(1, write)?; + 1u8.serialize(write)?; i.serialize(write)?; } Self::Parens(e) => { - serialize_u8(2, write)?; + 2u8.serialize(write)?; e.serialize(write)?; } Self::UnaryMinus(e) => { - serialize_u8(3, write)?; + 3u8.serialize(write)?; e.serialize(write)?; } Self::UnaryPlus(e) => { - serialize_u8(4, write)?; + 4u8.serialize(write)?; e.serialize(write)?; } Self::UnaryDiv(e) => { - serialize_u8(5, write)?; + 5u8.serialize(write)?; e.serialize(write)?; } Self::Factorial(e) => { - serialize_u8(6, write)?; + 6u8.serialize(write)?; e.serialize(write)?; } Self::Bop(op, a, b) => { - serialize_u8(7, write)?; + 7u8.serialize(write)?; op.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::Apply(a, b) => { - serialize_u8(8, write)?; + 8u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::ApplyFunctionCall(a, b) => { - serialize_u8(9, write)?; + 9u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::ApplyMul(a, b) => { - serialize_u8(10, write)?; + 10u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::As(a, b) => { - serialize_u8(11, write)?; + 11u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::Fn(a, b) => { - serialize_u8(12, write)?; + 12u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::Of(a, b) => { - serialize_u8(13, write)?; + 13u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::Assign(a, b) => { - serialize_u8(14, write)?; + 14u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } Self::Statements(a, b) => { - serialize_u8(15, write)?; + 15u8.serialize(write)?; a.serialize(write)?; b.serialize(write)?; } @@ -205,8 +206,8 @@ impl Expr { Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(match u8::deserialize(read)? { 0 => Self::Literal(Value::deserialize(read)?), 1 => Self::Ident(Ident::deserialize(read)?), 2 => Self::Parens(Box::new(Self::deserialize(read)?)), @@ -260,7 +261,7 @@ impl Expr { attrs: Attrs, ctx: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { Ok(match self { Self::Literal(Value::String(s)) => format!(r#""{}""#, s.as_ref()), Self::Literal(v) => v.format_to_plain_string(0, attrs, ctx, int)?, @@ -313,7 +314,7 @@ impl Expr { } /// returns true if rhs is '-1' or '(-1)' -fn should_compute_inverse(rhs: &Expr, int: &I) -> Result { +fn should_compute_inverse(rhs: &Expr, int: &I) -> FendCoreResult { if let Expr::UnaryMinus(inner) = rhs { if let Expr::Literal(Value::Num(n)) = &**inner { if n.is_unitless_one(int)? { @@ -339,7 +340,7 @@ pub(crate) fn evaluate( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { macro_rules! eval { ($e:expr) => { evaluate($e, scope.clone(), attrs, context, int) @@ -459,7 +460,7 @@ fn evaluate_add( b: Value, scope: Option>, int: &I, -) -> Result { +) -> FendCoreResult { Ok(match (a, b) { (Value::Num(a), Value::Num(b)) => Value::Num(Box::new(a.add(*b, int)?)), (Value::String(a), Value::String(b)) => { @@ -503,7 +504,7 @@ fn evaluate_as( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { if let Expr::Ident(ident) = &b { match ident.as_str() { "bool" | "boolean" => { @@ -580,7 +581,7 @@ pub(crate) fn resolve_identifier( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { macro_rules! eval_box { ($input:expr) => { Box::new(evaluate_to_value( diff --git a/core/src/date.rs b/core/src/date.rs index 69f74295..5ae6c1f0 100644 --- a/core/src/date.rs +++ b/core/src/date.rs @@ -11,7 +11,7 @@ pub(crate) use day_of_week::DayOfWeek; pub(crate) use month::Month; use year::Year; -use crate::{error::FendError, ident::Ident, value::Value}; +use crate::{error::FendError, ident::Ident, result::FendCoreResult, value::Value}; #[derive(Copy, Clone, Eq, PartialEq)] pub(crate) struct Date { @@ -21,7 +21,7 @@ pub(crate) struct Date { } impl Date { - pub(crate) fn today(context: &mut crate::Context) -> Result { + pub(crate) fn today(context: &mut crate::Context) -> FendCoreResult { let Some(current_time_info) = &context.current_time else { return Err(FendError::UnableToGetCurrentDate); }; @@ -120,7 +120,7 @@ impl Date { } } - pub(crate) fn diff_months(self, mut months: i64) -> Result { + pub(crate) fn diff_months(self, mut months: i64) -> FendCoreResult { let mut result = self; while months >= 12 { result.year = result.year.next(); @@ -170,18 +170,18 @@ impl Date { Ok(result) } - pub(crate) fn parse(s: &str) -> Result { + pub(crate) fn parse(s: &str) -> FendCoreResult { parser::parse_date(s) } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { self.year.serialize(write)?; self.month.serialize(write)?; self.day.serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { year: Year::deserialize(read)?, month: Month::deserialize(read)?, @@ -189,7 +189,7 @@ impl Date { }) } - pub(crate) fn get_object_member(self, key: &Ident) -> Result { + pub(crate) fn get_object_member(self, key: &Ident) -> FendCoreResult { Ok(match key.as_str() { "month" => Value::Month(self.month), "day_of_week" => Value::DayOfWeek(self.day_of_week()), @@ -197,7 +197,7 @@ impl Date { }) } - pub(crate) fn add(self, rhs: Value) -> Result { + pub(crate) fn add(self, rhs: Value) -> FendCoreResult { let rhs = rhs.expect_num()?; let int = &crate::interrupt::Never; if rhs.unit_equal_to("day") { @@ -212,7 +212,7 @@ impl Date { } } - pub(crate) fn sub(self, rhs: Value) -> Result { + pub(crate) fn sub(self, rhs: Value) -> FendCoreResult { let int = &crate::interrupt::Never; let rhs = rhs.expect_num()?; diff --git a/core/src/date/day.rs b/core/src/date/day.rs index 1ea281f9..e397813d 100644 --- a/core/src/date/day.rs +++ b/core/src/date/day.rs @@ -1,6 +1,6 @@ -use crate::serialize::deserialize_u8; -use crate::serialize::serialize_u8; +use crate::result::FendCoreResult; use crate::FendError; +use crate::{Deserialize, Serialize}; use std::fmt; use std::io; @@ -17,13 +17,13 @@ impl Day { Self(day) } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_u8(self.value(), write)?; + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.value().serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - let n = deserialize_u8(read)?; + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let n = u8::deserialize(read)?; if n == 0 || n >= 32 { return Err(FendError::DeserializationError); } diff --git a/core/src/date/day_of_week.rs b/core/src/date/day_of_week.rs index 3249555c..68c0ba95 100644 --- a/core/src/date/day_of_week.rs +++ b/core/src/date/day_of_week.rs @@ -1,6 +1,7 @@ use crate::{ error::FendError, - serialize::{deserialize_u8, serialize_u8}, + result::FendCoreResult, + serialize::{Deserialize, Serialize}, }; use std::{fmt, io}; @@ -43,13 +44,13 @@ impl DayOfWeek { } } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_u8(self.as_u8(), write)?; + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.as_u8().serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(match u8::deserialize(read)? { 0 => Self::Sunday, 1 => Self::Monday, 2 => Self::Tuesday, diff --git a/core/src/date/month.rs b/core/src/date/month.rs index 92520b2c..98600532 100644 --- a/core/src/date/month.rs +++ b/core/src/date/month.rs @@ -1,22 +1,25 @@ -use crate::serialize::serialize_u8; +use crate::result::FendCoreResult; use crate::FendError; -use crate::{date::Year, serialize::deserialize_u8}; +use crate::{ + date::Year, + serialize::{Deserialize, Serialize}, +}; use std::{convert, fmt, io}; #[derive(Copy, Clone, Eq, PartialEq)] pub(crate) enum Month { - January, - February, - March, - April, - May, - June, - July, - August, - September, - October, - November, - December, + January = 1, + February = 2, + March = 3, + April = 4, + May = 5, + June = 6, + July = 7, + August = 8, + September = 9, + October = 10, + November = 11, + December = 12, } impl Month { @@ -85,13 +88,13 @@ impl Month { } } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_u8(self.as_u8(), write)?; + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.as_u8().serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Self::try_from(deserialize_u8(read)?).map_err(|_| FendError::DeserializationError) + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Self::try_from(u8::deserialize(read)?).map_err(|_| FendError::DeserializationError) } fn as_u8(self) -> u8 { diff --git a/core/src/date/parser.rs b/core/src/date/parser.rs index 1d9f3632..d1645868 100644 --- a/core/src/date/parser.rs +++ b/core/src/date/parser.rs @@ -1,6 +1,7 @@ use crate::{ date::{Date, Day, Month, Year}, error::FendError, + result::FendCoreResult, }; use std::convert; @@ -59,7 +60,7 @@ fn parse_yyyymmdd(s: &str) -> Result<(Date, &str), ()> { Ok((Date { year, month, day }, s)) } -pub(crate) fn parse_date(s: &str) -> Result { +pub(crate) fn parse_date(s: &str) -> FendCoreResult { let trimmed = s.trim(); if let Ok((date, remaining)) = parse_yyyymmdd(trimmed) { if remaining.is_empty() { diff --git a/core/src/date/year.rs b/core/src/date/year.rs index b1e871ec..7a776cb4 100644 --- a/core/src/date/year.rs +++ b/core/src/date/year.rs @@ -2,7 +2,8 @@ use std::{convert, fmt, io}; use crate::{ error::FendError, - serialize::{deserialize_i32, serialize_i32}, + result::FendCoreResult, + serialize::{Deserialize, Serialize}, }; #[derive(Copy, Clone, Eq, PartialEq)] @@ -14,6 +15,7 @@ impl Year { Self(year) } + #[inline] pub(crate) fn value(self) -> i32 { self.0 } @@ -52,13 +54,13 @@ impl Year { } } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_i32(self.value(), write)?; + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.value().serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Self::try_from(deserialize_i32(read)?).map_err(|_| FendError::DeserializationError) + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Self::try_from(i32::deserialize(read)?).map_err(|_| FendError::DeserializationError) } } diff --git a/core/src/eval.rs b/core/src/eval.rs index 68bc565a..8ad7fba0 100644 --- a/core/src/eval.rs +++ b/core/src/eval.rs @@ -1,12 +1,7 @@ use std::sync::Arc; use crate::{ - ast, - error::{FendError, Interrupt}, - lexer, parser, - scope::Scope, - value::Value, - Span, + ast, error::Interrupt, lexer, parser, result::FendCoreResult, scope::Scope, value::Value, Span, }; pub(crate) fn evaluate_to_value( @@ -15,7 +10,7 @@ pub(crate) fn evaluate_to_value( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { let lex = lexer::lex(input, int); let mut tokens = vec![]; let mut missing_open_parens: i32 = 0; @@ -82,7 +77,7 @@ pub(crate) fn evaluate_to_spans( scope: Option>, context: &mut crate::Context, int: &I, -) -> Result<(Vec, bool, Attrs), FendError> { +) -> FendCoreResult<(Vec, bool, Attrs)> { let (attrs, input) = parse_attrs(input); let value = evaluate_to_value(input, scope, attrs, context, int)?; context.variables.insert("_".to_string(), value.clone()); diff --git a/core/src/format.rs b/core/src/format.rs index a3c709ca..2d9df91a 100644 --- a/core/src/format.rs +++ b/core/src/format.rs @@ -1,5 +1,6 @@ -use crate::error::{FendError, Interrupt}; +use crate::error::Interrupt; use crate::num::Exact; +use crate::result::FendCoreResult; use std::fmt; pub(crate) trait Format { @@ -10,10 +11,10 @@ pub(crate) trait Format { &self, params: &Self::Params, int: &I, - ) -> Result, FendError>; + ) -> FendCoreResult>; /// Simpler alternative to calling format - fn fm(&self, int: &I) -> Result { + fn fm(&self, int: &I) -> FendCoreResult { Ok(self.format(&Default::default(), int)?.value) } } diff --git a/core/src/ident.rs b/core/src/ident.rs index 5001fbeb..b6245369 100644 --- a/core/src/ident.rs +++ b/core/src/ident.rs @@ -1,8 +1,8 @@ use std::{borrow::Cow, fmt, io}; use crate::{ - error::FendError, - serialize::{deserialize_string, serialize_string}, + result::FendCoreResult, + serialize::{Deserialize, Serialize}, }; #[derive(Clone, Debug)] @@ -27,13 +27,12 @@ impl Ident { self.0 == "$" || self.0 == "\u{a3}" } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_string(self.0.as_ref(), write)?; - Ok(()) + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.0.as_ref().serialize(write) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(Self(Cow::Owned(deserialize_string(read)?))) + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(Self(Cow::Owned(String::deserialize(read)?))) } } diff --git a/core/src/interrupt.rs b/core/src/interrupt.rs index 834edfd6..f3feacfb 100644 --- a/core/src/interrupt.rs +++ b/core/src/interrupt.rs @@ -1,10 +1,10 @@ -use crate::error::FendError; +use crate::{error::FendError, result::FendCoreResult}; pub trait Interrupt { fn should_interrupt(&self) -> bool; } -pub(crate) fn test_int(int: &I) -> Result<(), FendError> { +pub(crate) fn test_int(int: &I) -> FendCoreResult<()> { if int.should_interrupt() { Err(FendError::Interrupted) } else { diff --git a/core/src/lexer.rs b/core/src/lexer.rs index 33db56af..1882bc9a 100644 --- a/core/src/lexer.rs +++ b/core/src/lexer.rs @@ -2,6 +2,7 @@ use crate::date::Date; use crate::error::{FendError, Interrupt}; use crate::ident::Ident; use crate::num::{Base, Number}; +use crate::result::FendCoreResult; use std::{borrow, convert, fmt}; #[derive(Clone, Debug)] @@ -72,7 +73,7 @@ impl fmt::Display for Symbol { } } -fn parse_char(input: &str) -> Result<(char, &str), FendError> { +fn parse_char(input: &str) -> FendCoreResult<(char, &str)> { input .chars() .next() @@ -82,7 +83,7 @@ fn parse_char(input: &str) -> Result<(char, &str), FendError> { }) } -fn parse_ascii_digit(input: &str, base: Base) -> Result<(u8, &str), FendError> { +fn parse_ascii_digit(input: &str, base: Base) -> FendCoreResult<(u8, &str)> { let (ch, input) = parse_char(input)?; let possible_digit = ch.to_digit(base.base_as_u8().into()); possible_digit @@ -92,7 +93,7 @@ fn parse_ascii_digit(input: &str, base: Base) -> Result<(u8, &str), FendError> { }) } -fn parse_fixed_char(input: &str, ch: char) -> Result<((), &str), FendError> { +fn parse_fixed_char(input: &str, ch: char) -> FendCoreResult<((), &str)> { let (parsed_ch, input) = parse_char(input)?; if parsed_ch == ch { Ok(((), input)) @@ -101,7 +102,7 @@ fn parse_fixed_char(input: &str, ch: char) -> Result<((), &str), FendError> { } } -fn parse_digit_separator(input: &str) -> Result<((), &str), FendError> { +fn parse_digit_separator(input: &str) -> FendCoreResult<((), &str)> { let (parsed_ch, input) = parse_char(input)?; if parsed_ch == '_' || parsed_ch == ',' { Ok(((), input)) @@ -147,7 +148,7 @@ fn parse_integer<'a, E: From>( Ok(((), input)) } -fn parse_base_prefix(input: &str) -> Result<(Base, &str), FendError> { +fn parse_base_prefix(input: &str) -> FendCoreResult<(Base, &str)> { // 0x -> 16 // 0o -> 8 // 0b -> 2 @@ -191,7 +192,7 @@ fn parse_recurring_digits<'a, I: Interrupt>( num_nonrec_digits: usize, base: Base, int: &I, -) -> Result<((), &'a str), FendError> { +) -> FendCoreResult<((), &'a str)> { let original_input = input; // If there's no '(': return Ok but don't parse anything if parse_fixed_char(input, '(').is_err() { @@ -205,7 +206,7 @@ fn parse_recurring_digits<'a, I: Interrupt>( let mut recurring_number_num = Number::from(0); let mut recurring_number_den = Number::from(1); let base_as_u64 = u64::from(base.base_as_u8()); - let ((), input) = parse_integer(input, true, base, &mut |digit| -> Result<(), FendError> { + let ((), input) = parse_integer(input, true, base, &mut |digit| -> FendCoreResult<()> { let digit_as_u64 = u64::from(digit); recurring_number_num = recurring_number_num .clone() @@ -231,7 +232,7 @@ fn parse_basic_number<'a, I: Interrupt>( mut input: &'a str, base: Base, int: &I, -) -> Result<(Number, &'a str), FendError> { +) -> FendCoreResult<(Number, &'a str)> { let mut is_dice_with_no_count = false; if input.starts_with('d') && base.base_as_u8() <= 10 { let mut chars = input.chars(); @@ -249,7 +250,7 @@ fn parse_basic_number<'a, I: Interrupt>( if parse_fixed_char(input, '.').is_err() && !is_dice_with_no_count { let ((), remaining) = - parse_integer(input, true, base, &mut |digit| -> Result<(), FendError> { + parse_integer(input, true, base, &mut |digit| -> FendCoreResult<()> { res = res .clone() .mul(base_as_u64.into(), int)? @@ -302,19 +303,15 @@ fn parse_basic_number<'a, I: Interrupt>( .map_err(|_| FendError::InvalidDiceSyntax)? }; let mut face_count = 0_u32; - let ((), remaining2) = parse_integer( - remaining, - false, - base, - &mut |digit| -> Result<(), FendError> { + let ((), remaining2) = + parse_integer(remaining, false, base, &mut |digit| -> FendCoreResult<()> { face_count = face_count .checked_mul(base.base_as_u8().into()) .ok_or(FendError::InvalidDiceSyntax)? .checked_add(digit.into()) .ok_or(FendError::InvalidDiceSyntax)?; Ok(()) - }, - )?; + })?; if dice_count == 0 || face_count == 0 { return Err(FendError::InvalidDiceSyntax); } @@ -360,7 +357,7 @@ fn parse_basic_number<'a, I: Interrupt>( let mut exp = Number::zero_with_base(base); let base_num = Number::from(u64::from(base.base_as_u8())); let ((), remaining2) = - parse_integer(input, true, base, &mut |digit| -> Result<(), FendError> { + parse_integer(input, true, base, &mut |digit| -> FendCoreResult<()> { exp = (exp.clone().mul(base_num.clone(), int)?) .add(u64::from(digit).into(), int)?; Ok(()) @@ -378,7 +375,7 @@ fn parse_basic_number<'a, I: Interrupt>( Ok((res, input)) } -fn parse_number<'a, I: Interrupt>(input: &'a str, int: &I) -> Result<(Number, &'a str), FendError> { +fn parse_number<'a, I: Interrupt>(input: &'a str, int: &I) -> FendCoreResult<(Number, &'a str)> { let (base, input) = parse_base_prefix(input).unwrap_or((Base::default(), input)); let (res, input) = parse_basic_number(input, base, int)?; Ok((res, input)) @@ -418,7 +415,7 @@ fn is_valid_in_ident(ch: char, prev: Option) -> bool { } } -fn parse_ident(input: &str, allow_dots: bool) -> Result<(Token, &str), FendError> { +fn parse_ident(input: &str, allow_dots: bool) -> FendCoreResult<(Token, &str)> { let (first_char, _) = parse_char(input)?; if !is_valid_in_ident(first_char, None) || first_char == '.' && !allow_dots { return Err(FendError::InvalidCharAtBeginningOfIdent(first_char)); @@ -452,7 +449,7 @@ fn parse_ident(input: &str, allow_dots: bool) -> Result<(Token, &str), FendError )) } -fn parse_symbol(ch: char, input: &mut &str) -> Result { +fn parse_symbol(ch: char, input: &mut &str) -> FendCoreResult { let mut test_next = |next: char| { if input.starts_with(next) { let (_, remaining) = input.split_at(next.len_utf8()); @@ -509,7 +506,7 @@ fn parse_symbol(ch: char, input: &mut &str) -> Result { })) } -fn parse_unicode_escape(chars_iter: &mut std::str::CharIndices<'_>) -> Result { +fn parse_unicode_escape(chars_iter: &mut std::str::CharIndices<'_>) -> FendCoreResult { if chars_iter .next() .ok_or(FendError::UnterminatedStringLiteral)? @@ -548,7 +545,7 @@ fn parse_unicode_escape(chars_iter: &mut std::str::CharIndices<'_>) -> Result Result<(Token, &str), FendError> { +fn parse_string_literal(input: &str, terminator: char) -> FendCoreResult<(Token, &str)> { let (_, input) = input.split_at(1); let mut chars_iter = input.char_indices(); let mut literal_length = None; @@ -685,7 +682,7 @@ fn skip_whitespace_and_comments(input: &mut &str) { } } -fn parse_date(input: &str) -> Result<(Date, &str), FendError> { +fn parse_date(input: &str) -> FendCoreResult<(Date, &str)> { let (_, input) = input.split_at(1); // skip '@' symbol let mut input2 = input; let mut split_idx = 0; @@ -716,7 +713,7 @@ fn parse_date(input: &str) -> Result<(Date, &str), FendError> { } impl<'a, 'b, I: Interrupt> Lexer<'a, 'b, I> { - fn next_token(&mut self) -> Result, FendError> { + fn next_token(&mut self) -> FendCoreResult> { skip_whitespace_and_comments(&mut self.input); let (ch, following) = { let mut chars = self.input.chars(); @@ -779,7 +776,7 @@ impl<'a, 'b, I: Interrupt> Lexer<'a, 'b, I> { } impl<'a, I: Interrupt> Iterator for Lexer<'a, '_, I> { - type Item = Result; + type Item = FendCoreResult; fn next(&mut self) -> Option { let res = match self.next_token() { diff --git a/core/src/lib.rs b/core/src/lib.rs index 35c98bee..f4edeed2 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -33,6 +33,7 @@ pub mod json; mod lexer; mod num; mod parser; +mod result; mod scope; mod serialize; mod units; @@ -44,7 +45,8 @@ use std::{collections::HashMap, fmt, io}; use error::FendError; pub(crate) use eval::Attrs; pub use interrupt::Interrupt; -use serialize::{deserialize_string, deserialize_usize, serialize_string, serialize_usize}; +use result::FendCoreResult; +use serialize::{Deserialize, Serialize}; /// This contains the result of a computation. #[derive(PartialEq, Eq, Debug)] @@ -280,10 +282,10 @@ impl Context { self.output_mode = OutputMode::TerminalFixedWidth; } - fn serialize_variables_internal(&self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_usize(self.variables.len(), write)?; + fn serialize_variables_internal(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.variables.len().serialize(write)?; for (k, v) in &self.variables { - serialize_string(k.as_str(), write)?; + k.as_str().serialize(write)?; v.serialize(write)?; } Ok(()) @@ -303,16 +305,14 @@ impl Context { } } - fn deserialize_variables_internal( - &mut self, - read: &mut impl io::Read, - ) -> Result<(), FendError> { - let len = deserialize_usize(read)?; + fn deserialize_variables_internal(&mut self, read: &mut impl io::Read) -> FendCoreResult<()> { + let len = usize::deserialize(read)?; self.variables.clear(); self.variables.reserve(len); for _ in 0..len { - self.variables - .insert(deserialize_string(read)?, value::Value::deserialize(read)?); + let s = String::deserialize(read)?; + let v = value::Value::deserialize(read)?; + self.variables.insert(s, v); } Ok(()) } diff --git a/core/src/num/base.rs b/core/src/num/base.rs index e3431467..98f2f573 100644 --- a/core/src/num/base.rs +++ b/core/src/num/base.rs @@ -2,7 +2,8 @@ use std::{fmt, io}; use crate::{ error::FendError, - serialize::{deserialize_u8, serialize_u8}, + result::FendCoreResult, + serialize::{Deserialize, Serialize}, }; #[derive(Copy, Clone, PartialEq, Eq)] @@ -34,7 +35,7 @@ impl Base { } } - pub(crate) const fn from_zero_based_prefix_char(ch: char) -> Result { + pub(crate) const fn from_zero_based_prefix_char(ch: char) -> FendCoreResult { Ok(match ch { 'x' => Self(BaseEnum::Hex), 'o' => Self(BaseEnum::Octal), @@ -43,7 +44,7 @@ impl Base { }) } - pub(crate) const fn from_plain_base(base: u8) -> Result { + pub(crate) const fn from_plain_base(base: u8) -> FendCoreResult { if base < 2 { return Err(FendError::BaseTooSmall); } else if base > 36 { @@ -52,7 +53,7 @@ impl Base { Ok(Self(BaseEnum::Plain(base))) } - pub(crate) const fn from_custom_base(base: u8) -> Result { + pub(crate) const fn from_custom_base(base: u8) -> FendCoreResult { if base < 2 { return Err(FendError::BaseTooSmall); } else if base > 36 { @@ -118,30 +119,30 @@ impl Base { }) } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { match self.0 { - BaseEnum::Binary => serialize_u8(1, write)?, - BaseEnum::Octal => serialize_u8(2, write)?, - BaseEnum::Hex => serialize_u8(3, write)?, + BaseEnum::Binary => 1u8.serialize(write)?, + BaseEnum::Octal => 2u8.serialize(write)?, + BaseEnum::Hex => 3u8.serialize(write)?, BaseEnum::Custom(b) => { - serialize_u8(4, write)?; - serialize_u8(b, write)?; + 4u8.serialize(write)?; + b.serialize(write)?; } BaseEnum::Plain(b) => { - serialize_u8(5, write)?; - serialize_u8(b, write)?; + 5u8.serialize(write)?; + b.serialize(write)?; } } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(Self(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(Self(match u8::deserialize(read)? { 1 => BaseEnum::Binary, 2 => BaseEnum::Octal, 3 => BaseEnum::Hex, - 4 => BaseEnum::Custom(deserialize_u8(read)?), - 5 => BaseEnum::Plain(deserialize_u8(read)?), + 4 => BaseEnum::Custom(u8::deserialize(read)?), + 5 => BaseEnum::Plain(u8::deserialize(read)?), _ => return Err(FendError::DeserializationError), })) } diff --git a/core/src/num/bigrat.rs b/core/src/num/bigrat.rs index a1298f33..cc5d6ade 100644 --- a/core/src/num/bigrat.rs +++ b/core/src/num/bigrat.rs @@ -3,19 +3,21 @@ use crate::format::Format; use crate::interrupt::test_int; use crate::num::biguint::BigUint; use crate::num::{Base, Exact, FormattingStyle, Range, RangeBound}; +use crate::result::FendCoreResult; use std::{cmp, fmt, hash, io, ops}; pub(crate) mod sign { use crate::{ error::FendError, - serialize::{deserialize_u8, serialize_u8}, + result::FendCoreResult, + serialize::{Deserialize, Serialize}, }; use std::io; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) enum Sign { - Negative, - Positive, + Negative = 1, + Positive = 2, } impl Sign { @@ -37,18 +39,12 @@ pub(crate) mod sign { } } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - Ok(serialize_u8( - match self { - Self::Positive => 1, - Self::Negative => 2, - }, - write, - )?) + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + (self as u8).serialize(write) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(match u8::deserialize(read)? { 1 => Self::Positive, 2 => Self::Negative, _ => return Err(FendError::DeserializationError), @@ -121,14 +117,14 @@ impl hash::Hash for BigRat { } impl BigRat { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { self.sign.serialize(write)?; self.num.serialize(write)?; self.den.serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { sign: Sign::deserialize(read)?, num: BigUint::deserialize(read)?, @@ -140,7 +136,7 @@ impl BigRat { self.den == 1.into() } - pub(crate) fn try_as_usize(mut self, int: &I) -> Result { + pub(crate) fn try_as_usize(mut self, int: &I) -> FendCoreResult { if self.sign == Sign::Negative && self.num != 0.into() { return Err(FendError::NegativeNumbersNotAllowed); } @@ -151,7 +147,7 @@ impl BigRat { self.num.try_as_usize(int) } - pub(crate) fn try_as_i64(mut self, int: &I) -> Result { + pub(crate) fn try_as_i64(mut self, int: &I) -> FendCoreResult { self = self.simplify(int)?; if self.den != 1.into() { return Err(FendError::FractionToInteger); @@ -170,7 +166,7 @@ impl BigRat { }) } - pub(crate) fn into_f64(mut self, int: &I) -> Result { + pub(crate) fn into_f64(mut self, int: &I) -> FendCoreResult { if self.is_definitely_zero() { return Ok(0.0); } @@ -188,7 +184,7 @@ impl BigRat { clippy::cast_sign_loss, clippy::cast_precision_loss )] - pub(crate) fn from_f64(mut f: f64, int: &I) -> Result { + pub(crate) fn from_f64(mut f: f64, int: &I) -> FendCoreResult { let negative = f < 0.0; if negative { f = -f; @@ -209,7 +205,7 @@ impl BigRat { } // sin works for all real numbers - pub(crate) fn sin(self, int: &I) -> Result, FendError> { + pub(crate) fn sin(self, int: &I) -> FendCoreResult> { Ok(if self == 0.into() { Exact::new(Self::from(0), true) } else { @@ -218,7 +214,7 @@ impl BigRat { } // asin, acos and atan only work for values between -1 and 1 - pub(crate) fn asin(self, int: &I) -> Result { + pub(crate) fn asin(self, int: &I) -> FendCoreResult { let one = Self::from(1); if self > one || self < -one { return Err(out_of_range(self.fm(int)?, Range::open(-1, 1))); @@ -226,7 +222,7 @@ impl BigRat { Self::from_f64(f64::asin(self.into_f64(int)?), int) } - pub(crate) fn acos(self, int: &I) -> Result { + pub(crate) fn acos(self, int: &I) -> FendCoreResult { let one = Self::from(1); if self > one || self < -one { return Err(out_of_range(self.fm(int)?, Range::open(-1, 1))); @@ -235,32 +231,32 @@ impl BigRat { } // note that this works for any real number, unlike asin and acos - pub(crate) fn atan(self, int: &I) -> Result { + pub(crate) fn atan(self, int: &I) -> FendCoreResult { Self::from_f64(f64::atan(self.into_f64(int)?), int) } - pub(crate) fn atan2(self, rhs: Self, int: &I) -> Result { + pub(crate) fn atan2(self, rhs: Self, int: &I) -> FendCoreResult { Self::from_f64(f64::atan2(self.into_f64(int)?, rhs.into_f64(int)?), int) } - pub(crate) fn sinh(self, int: &I) -> Result { + pub(crate) fn sinh(self, int: &I) -> FendCoreResult { Self::from_f64(f64::sinh(self.into_f64(int)?), int) } - pub(crate) fn cosh(self, int: &I) -> Result { + pub(crate) fn cosh(self, int: &I) -> FendCoreResult { Self::from_f64(f64::cosh(self.into_f64(int)?), int) } - pub(crate) fn tanh(self, int: &I) -> Result { + pub(crate) fn tanh(self, int: &I) -> FendCoreResult { Self::from_f64(f64::tanh(self.into_f64(int)?), int) } - pub(crate) fn asinh(self, int: &I) -> Result { + pub(crate) fn asinh(self, int: &I) -> FendCoreResult { Self::from_f64(f64::asinh(self.into_f64(int)?), int) } // value must not be less than 1 - pub(crate) fn acosh(self, int: &I) -> Result { + pub(crate) fn acosh(self, int: &I) -> FendCoreResult { if self < 1.into() { return Err(out_of_range( self.fm(int)?, @@ -274,7 +270,7 @@ impl BigRat { } // value must be between -1 and 1. - pub(crate) fn atanh(self, int: &I) -> Result { + pub(crate) fn atanh(self, int: &I) -> FendCoreResult { let one: Self = 1.into(); if self >= one || self <= -one { return Err(out_of_range(self.fm(int)?, Range::open(-1, 1))); @@ -283,7 +279,7 @@ impl BigRat { } // For all logs: value must be greater than 0 - pub(crate) fn ln(self, int: &I) -> Result, FendError> { + pub(crate) fn ln(self, int: &I) -> FendCoreResult> { if self <= 0.into() { return Err(out_of_range( self.fm(int)?, @@ -302,7 +298,7 @@ impl BigRat { )) } - pub(crate) fn log2(self, int: &I) -> Result { + pub(crate) fn log2(self, int: &I) -> FendCoreResult { if self <= 0.into() { return Err(out_of_range( self.fm(int)?, @@ -315,7 +311,7 @@ impl BigRat { Self::from_f64(f64::log2(self.into_f64(int)?), int) } - pub(crate) fn log10(self, int: &I) -> Result { + pub(crate) fn log10(self, int: &I) -> FendCoreResult { if self <= 0.into() { return Err(out_of_range( self.fm(int)?, @@ -330,9 +326,9 @@ impl BigRat { fn apply_uint_op( mut self, - f: impl FnOnce(BigUint, &I) -> Result, + f: impl FnOnce(BigUint, &I) -> FendCoreResult, int: &I, - ) -> Result { + ) -> FendCoreResult { self = self.simplify(int)?; if self.den != 1.into() { let n = self.fm(int)?; @@ -344,7 +340,7 @@ impl BigRat { f(self.num, int) } - pub(crate) fn factorial(self, int: &I) -> Result { + pub(crate) fn factorial(self, int: &I) -> FendCoreResult { Ok(self.apply_uint_op(BigUint::factorial, int)?.into()) } @@ -353,7 +349,7 @@ impl BigRat { rhs: Self, op: crate::ast::BitwiseBop, int: &I, - ) -> Result { + ) -> FendCoreResult { use crate::ast::BitwiseBop; Ok(self @@ -375,7 +371,7 @@ impl BigRat { } /// compute a + b - fn add_internal(self, rhs: Self, int: &I) -> Result { + fn add_internal(self, rhs: Self, int: &I) -> FendCoreResult { // a + b == -((-a) + (-b)) if self.sign == Sign::Negative { return Ok(-((-self).add_internal(-rhs, int)?)); @@ -427,7 +423,7 @@ impl BigRat { }) } - fn simplify(mut self, int: &I) -> Result { + fn simplify(mut self, int: &I) -> FendCoreResult { if self.den == 1.into() { return Ok(self); } @@ -437,7 +433,7 @@ impl BigRat { Ok(self) } - pub(crate) fn div(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn div(self, rhs: &Self, int: &I) -> FendCoreResult { if rhs.num == 0.into() { return Err(FendError::DivideByZero); } @@ -448,11 +444,7 @@ impl BigRat { }) } - pub(crate) fn modulo( - mut self, - mut rhs: Self, - int: &I, - ) -> Result { + pub(crate) fn modulo(mut self, mut rhs: Self, int: &I) -> FendCoreResult { if rhs.num == 0.into() { return Err(FendError::ModuloByZero); } @@ -474,7 +466,7 @@ impl BigRat { // test if this fraction has a terminating representation // e.g. in base 10: 1/4 = 0.25, but not 1/3 - fn terminates_in_base(&self, base: Base, int: &I) -> Result { + fn terminates_in_base(&self, base: Base, int: &I) -> FendCoreResult { let mut x = self.clone(); let base_as_u64: u64 = base.base_as_u8().into(); let base = Self { @@ -501,7 +493,7 @@ impl BigRat { use_parens_if_product: bool, sf_limit: Option, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let (ty, exact) = if !term.is_empty() && !base.has_prefix() && num == &1.into() { (FormattedBigRatType::Integer(None, false, term, false), true) } else { @@ -535,7 +527,7 @@ impl BigRat { mixed: bool, use_parens: bool, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let format_options = biguint::FormatOptions { base, write_base_prefix: true, @@ -603,9 +595,9 @@ impl BigRat { base: Base, sign: Sign, term: &'static str, - mut terminating: impl FnMut() -> Result, + mut terminating: impl FnMut() -> FendCoreResult, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let integer_part = self.clone().num.div(&self.den, int)?; let sf_limit = if let FormattingStyle::SignificantFigures(sf) = style { Some(sf) @@ -697,10 +689,10 @@ impl BigRat { numerator: &BigUint, denominator: &BigUint, max_digits: MaxDigitsToPrint, - mut terminating: impl FnMut() -> Result, - print_integer_part: impl Fn(bool) -> Result<(Sign, String), FendError>, + mut terminating: impl FnMut() -> FendCoreResult, + print_integer_part: impl Fn(bool) -> FendCoreResult<(Sign, String)>, int: &I, - ) -> Result<(Sign, Exact), FendError> { + ) -> FendCoreResult<(Sign, Exact)> { let base_as_u64: u64 = base.base_as_u8().into(); let b: BigUint = base_as_u64.into(); let next_digit = @@ -719,7 +711,7 @@ impl BigRat { let next_num = bnum.sub(&digit.clone().mul(denominator, int)?); Ok((next_num, digit)) }; - let fold_digits = |mut s: String, digit: BigUint| -> Result { + let fold_digits = |mut s: String, digit: BigUint| -> FendCoreResult { let digit_str = digit .format( &biguint::FormatOptions { @@ -779,9 +771,9 @@ impl BigRat { base: Base, ignore_number_of_leading_zeroes: bool, mut next_digit: impl FnMut(usize, BigUint, &BigUint) -> Result<(BigUint, BigUint), NextDigitErr>, - print_integer_part: impl Fn(bool) -> Result<(Sign, String), FendError>, + print_integer_part: impl Fn(bool) -> FendCoreResult<(Sign, String)>, int: &I, - ) -> Result<(Sign, Exact), FendError> { + ) -> FendCoreResult<(Sign, Exact)> { let mut current_numerator = numerator.clone(); let mut i = 0; let mut trailing_zeroes = 0; @@ -908,7 +900,7 @@ impl BigRat { mut self, mut rhs: Self, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { self = self.simplify(int)?; rhs = rhs.simplify(int)?; if self.num != 0.into() && self.sign == Sign::Negative && rhs.den != 1.into() { @@ -953,7 +945,7 @@ impl BigRat { val: &Self, n: &Self, int: &I, - ) -> Result { + ) -> FendCoreResult { let mut high_bound = low_bound.clone().add(1.into(), int)?; for _ in 0..30 { let guess = low_bound @@ -969,7 +961,7 @@ impl BigRat { low_bound.add(high_bound, int)?.div(&2.into(), int) } - pub(crate) fn exp(self, int: &I) -> Result, FendError> { + pub(crate) fn exp(self, int: &I) -> FendCoreResult> { if self.num == 0.into() { return Ok(Exact::new(Self::from(1), true)); } @@ -981,7 +973,7 @@ impl BigRat { // the boolean indicates whether or not the result is exact // n must be an integer - pub(crate) fn root_n(self, n: &Self, int: &I) -> Result, FendError> { + pub(crate) fn root_n(self, n: &Self, int: &I) -> FendCoreResult> { if self.num != 0.into() && self.sign == Sign::Negative { return Err(FendError::RootsOfNegativeNumbers); } @@ -1029,7 +1021,7 @@ impl BigRat { Ok(Exact::new(num_rat.div(&den_rat, int)?, false)) } - pub(crate) fn mul(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn mul(self, rhs: &Self, int: &I) -> FendCoreResult { Ok(Self { sign: Sign::sign_of_product(self.sign, rhs.sign), num: self.num.mul(&rhs.num, int)?, @@ -1037,7 +1029,7 @@ impl BigRat { }) } - pub(crate) fn add(self, rhs: Self, int: &I) -> Result { + pub(crate) fn add(self, rhs: Self, int: &I) -> FendCoreResult { self.add_internal(rhs, int) } @@ -1049,7 +1041,7 @@ impl BigRat { self.sign == Sign::Positive && self.num.is_definitely_one() && self.den.is_definitely_one() } - pub(crate) fn combination(self, rhs: Self, int: &I) -> Result { + pub(crate) fn combination(self, rhs: Self, int: &I) -> FendCoreResult { let n_factorial = self.clone().factorial(int)?; let r_factorial = rhs.clone().factorial(int)?; let n_minus_r_factorial = self.add(-rhs, int)?.factorial(int)?; @@ -1057,7 +1049,7 @@ impl BigRat { n_factorial.div(&denominator, int) } - pub(crate) fn permutation(self, rhs: Self, int: &I) -> Result { + pub(crate) fn permutation(self, rhs: Self, int: &I) -> FendCoreResult { let n_factorial = self.clone().factorial(int)?; let n_minus_r_factorial = self.add(-rhs, int)?.factorial(int)?; n_factorial.div(&n_minus_r_factorial, int) @@ -1134,7 +1126,7 @@ impl Format for BigRat { &self, params: &Self::Params, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let base = params.base; let style = params.style; let term = params.term; @@ -1285,8 +1277,9 @@ impl fmt::Display for FormattedBigRat { mod tests { use super::sign::Sign; use super::BigRat; - use crate::error::FendError; + use crate::num::biguint::BigUint; + use crate::result::FendCoreResult; use std::mem; #[test] @@ -1298,7 +1291,7 @@ mod tests { } #[test] - fn test_addition() -> Result<(), FendError> { + fn test_addition() -> FendCoreResult<()> { let int = &crate::interrupt::Never; let two = BigRat::from(2); assert_eq!(two.clone().add(two, int)?, BigRat::from(4)); diff --git a/core/src/num/biguint.rs b/core/src/num/biguint.rs index 036b469d..6a21658c 100644 --- a/core/src/num/biguint.rs +++ b/core/src/num/biguint.rs @@ -2,10 +2,8 @@ use crate::error::{FendError, Interrupt}; use crate::format::Format; use crate::interrupt::test_int; use crate::num::{out_of_range, Base, Exact, Range, RangeBound}; -use crate::serialize::{ - deserialize_u64, deserialize_u8, deserialize_usize, serialize_u64, serialize_u8, - serialize_usize, -}; +use crate::result::FendCoreResult; +use crate::serialize::{Deserialize, Serialize}; use std::cmp::{max, Ordering}; use std::{fmt, hash, io}; @@ -70,8 +68,8 @@ impl BigUint { } } - pub(crate) fn try_as_usize(&self, int: &I) -> Result { - let error = || -> Result<_, FendError> { + pub(crate) fn try_as_usize(&self, int: &I) -> FendCoreResult { + let error = || -> FendCoreResult<_> { Ok(out_of_range( self.fm(int)?, Range { @@ -167,7 +165,7 @@ impl BigUint { } } - pub(crate) fn gcd(mut a: Self, mut b: Self, int: &I) -> Result { + pub(crate) fn gcd(mut a: Self, mut b: Self, int: &I) -> FendCoreResult { while b >= 1.into() { let r = a.rem(&b, int)?; a = b; @@ -177,7 +175,7 @@ impl BigUint { Ok(a) } - pub(crate) fn pow(a: &Self, b: &Self, int: &I) -> Result { + pub(crate) fn pow(a: &Self, b: &Self, int: &I) -> FendCoreResult { if a.is_zero() && b.is_zero() { return Err(FendError::ZeroToThePowerOfZero); } @@ -192,7 +190,7 @@ impl BigUint { // computes the exact `n`-th root if possible, otherwise the next lower integer #[allow(clippy::redundant_clone)] - pub(crate) fn root_n(self, n: &Self, int: &I) -> Result, FendError> { + pub(crate) fn root_n(self, n: &Self, int: &I) -> FendCoreResult> { if self == 0.into() || self == 1.into() || n == &Self::from(1) { return Ok(Exact::new(self, true)); } @@ -213,7 +211,7 @@ impl BigUint { Ok(Exact::new(low_guess, false)) } - fn pow_internal(&self, mut exponent: u64, int: &I) -> Result { + fn pow_internal(&self, mut exponent: u64, int: &I) -> FendCoreResult { let mut result = Self::from(1); let mut base = self.clone(); while exponent > 0 { @@ -227,7 +225,7 @@ impl BigUint { Ok(result) } - fn lshift(&mut self, int: &I) -> Result<(), FendError> { + fn lshift(&mut self, int: &I) -> FendCoreResult<()> { match self { Small(n) => { if *n & 0xc000_0000_0000_0000 == 0 { @@ -252,7 +250,7 @@ impl BigUint { Ok(()) } - fn rshift(&mut self, int: &I) -> Result<(), FendError> { + fn rshift(&mut self, int: &I) -> FendCoreResult<()> { match self { Small(n) => *n >>= 1, Large(value) => { @@ -275,7 +273,7 @@ impl BigUint { &self, other: &Self, int: &I, - ) -> Result<(Self, Self), FendError> { + ) -> FendCoreResult<(Self, Self)> { if let (Small(a), Small(b)) = (self, other) { if let (Some(div_res), Some(mod_res)) = (a.checked_div(*b), a.checked_rem(*b)) { return Ok((Small(div_res), Small(mod_res))); @@ -322,7 +320,7 @@ impl BigUint { } /// computes self *= other - fn mul_internal(&mut self, other: &Self, int: &I) -> Result<(), FendError> { + fn mul_internal(&mut self, other: &Self, int: &I) -> FendCoreResult<()> { if self.is_zero() || other.is_zero() { *self = Self::from(0); return Ok(()); @@ -359,7 +357,7 @@ impl BigUint { } // Note: 0! = 1, 1! = 1 - pub(crate) fn factorial(mut self, int: &I) -> Result { + pub(crate) fn factorial(mut self, int: &I) -> FendCoreResult { let mut res = Self::from(1); while self > 1.into() { test_int(int)?; @@ -369,7 +367,7 @@ impl BigUint { Ok(res) } - pub(crate) fn mul(mut self, other: &Self, int: &I) -> Result { + pub(crate) fn mul(mut self, other: &Self, int: &I) -> FendCoreResult { if let (Small(a), Small(b)) = (&self, &other) { if let Some(res) = a.checked_mul(*b) { return Ok(Self::from(res)); @@ -379,15 +377,15 @@ impl BigUint { Ok(self) } - fn rem(&self, other: &Self, int: &I) -> Result { + fn rem(&self, other: &Self, int: &I) -> FendCoreResult { Ok(self.divmod(other, int)?.1) } - pub(crate) fn is_even(&self, int: &I) -> Result { + pub(crate) fn is_even(&self, int: &I) -> FendCoreResult { Ok(self.divmod(&Self::from(2), int)?.1 == 0.into()) } - pub(crate) fn div(self, other: &Self, int: &I) -> Result { + pub(crate) fn div(self, other: &Self, int: &I) -> FendCoreResult { Ok(self.divmod(other, int)?.0) } @@ -446,32 +444,32 @@ impl BigUint { } } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { match self { Small(x) => { - serialize_u8(1, write)?; - serialize_u64(*x, write)?; + 1u8.serialize(write)?; + x.serialize(write)?; } Large(v) => { - serialize_u8(2, write)?; - serialize_usize(v.len(), write)?; + 2u8.serialize(write)?; + v.len().serialize(write)?; for b in v { - serialize_u64(*b, write)?; + b.serialize(write)?; } } } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - let kind = deserialize_u8(read)?; + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let kind = u8::deserialize(read)?; Ok(match kind { - 1 => Self::Small(deserialize_u64(read)?), + 1 => Self::Small(u64::deserialize(read)?), 2 => { - let len = deserialize_usize(read)?; + let len = usize::deserialize(read)?; let mut v = Vec::with_capacity(len); for _ in 0..len { - v.push(deserialize_u64(read)?); + v.push(u64::deserialize(read)?); } Self::Large(v) } @@ -542,7 +540,7 @@ impl BigUint { } } - pub(crate) fn lshift_n(mut self, rhs: &Self, int: &I) -> Result { + pub(crate) fn lshift_n(mut self, rhs: &Self, int: &I) -> FendCoreResult { let mut rhs = rhs.try_as_usize(int)?; if rhs > 64 { self.make_large(); @@ -562,7 +560,7 @@ impl BigUint { Ok(self) } - pub(crate) fn rshift_n(mut self, rhs: &Self, int: &I) -> Result { + pub(crate) fn rshift_n(mut self, rhs: &Self, int: &I) -> FendCoreResult { let rhs = rhs.try_as_usize(int)?; for _ in 0..rhs { if self.is_zero() { @@ -651,7 +649,7 @@ impl Format for BigUint { &self, params: &Self::Params, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let base_prefix = if params.write_base_prefix { Some(params.base) } else { diff --git a/core/src/num/complex.rs b/core/src/num/complex.rs index 531a9b43..8bbd8580 100644 --- a/core/src/num/complex.rs +++ b/core/src/num/complex.rs @@ -2,6 +2,7 @@ use crate::error::{FendError, Interrupt}; use crate::num::real::{self, Real}; use crate::num::Exact; use crate::num::{Base, FormattingStyle}; +use crate::result::FendCoreResult; use std::cmp::Ordering; use std::ops::Neg; use std::{fmt, io}; @@ -30,27 +31,27 @@ pub(crate) enum UseParentheses { } impl Complex { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { self.real.serialize(write)?; self.imag.serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { real: Real::deserialize(read)?, imag: Real::deserialize(read)?, }) } - pub(crate) fn try_as_usize(self, int: &I) -> Result { + pub(crate) fn try_as_usize(self, int: &I) -> FendCoreResult { if self.imag != 0.into() { return Err(FendError::ComplexToInteger); } self.real.try_as_usize(int) } - pub(crate) fn try_as_i64(self, int: &I) -> Result { + pub(crate) fn try_as_i64(self, int: &I) -> FendCoreResult { if self.imag != 0.into() { return Err(FendError::ComplexToInteger); } @@ -74,7 +75,7 @@ impl Complex { } } - pub(crate) fn factorial(self, int: &I) -> Result { + pub(crate) fn factorial(self, int: &I) -> FendCoreResult { if self.imag != 0.into() { return Err(FendError::FactorialComplex); } @@ -84,7 +85,7 @@ impl Complex { }) } - pub(crate) fn exp(self, int: &I) -> Result, FendError> { + pub(crate) fn exp(self, int: &I) -> FendCoreResult> { // e^(a + bi) = e^a * e^(bi) = e^a * (cos(b) + i * sin(b)) let r = self.real.exp(int)?; let exact = r.exact; @@ -98,7 +99,7 @@ impl Complex { )) } - fn pow_n(self, n: usize, int: &I) -> Result, FendError> { + fn pow_n(self, n: usize, int: &I) -> FendCoreResult> { if n == 0 { return Ok(Exact::new(Self::from(1), true)); } @@ -117,7 +118,7 @@ impl Complex { Ok(result) } - pub(crate) fn pow(self, rhs: Self, int: &I) -> Result, FendError> { + pub(crate) fn pow(self, rhs: Self, int: &I) -> FendCoreResult> { if !rhs.real.is_integer() || !rhs.imag.is_integer() { return self.frac_pow(rhs, int); } @@ -190,7 +191,7 @@ impl Complex { } } - pub(crate) fn abs(self, int: &I) -> Result, FendError> { + pub(crate) fn abs(self, int: &I) -> FendCoreResult> { Ok(if self.imag.is_zero() { if self.real < 0.into() { Exact::new(-self.real, true) @@ -212,7 +213,7 @@ impl Complex { }) } - pub(crate) fn arg(self, int: &I) -> Result, FendError> { + pub(crate) fn arg(self, int: &I) -> FendCoreResult> { Ok(Exact::new(self.imag.atan2(self.real, int)?, false)) } @@ -223,7 +224,7 @@ impl Complex { base: Base, use_parentheses: UseParentheses, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let style = if !exact && style == FormattingStyle::Auto { FormattingStyle::DecimalPlaces(10) } else if self.imag != 0.into() && style == FormattingStyle::Auto { @@ -284,7 +285,7 @@ impl Complex { ) }) } - pub(crate) fn frac_pow(self, n: Self, int: &I) -> Result, FendError> { + pub(crate) fn frac_pow(self, n: Self, int: &I) -> FendCoreResult> { if self.imag.is_zero() && n.imag.is_zero() && self.real >= 0.into() { Ok(self.real.pow(n.real, int)?.apply(Self::from)) } else { @@ -293,7 +294,7 @@ impl Complex { } } - fn expect_real(self) -> Result { + fn expect_real(self) -> FendCoreResult { if self.imag.is_zero() { Ok(self.real) } else { @@ -301,7 +302,7 @@ impl Complex { } } - pub(crate) fn sin(self, int: &I) -> Result, FendError> { + pub(crate) fn sin(self, int: &I) -> FendCoreResult> { // sin(a + bi) = sin(a) * cosh(b) + i * cos(a) * sinh(b) if self.imag.is_zero() { Ok(self.real.sin(int)?.apply(Self::from)) @@ -322,7 +323,7 @@ impl Complex { } } - pub(crate) fn cos(self, int: &I) -> Result, FendError> { + pub(crate) fn cos(self, int: &I) -> FendCoreResult> { // cos(a + bi) = cos(a) * cosh(b) - i * sin(a) * sinh(b) if self.imag.is_zero() { Ok(self.real.cos(int)?.apply(Self::from)) @@ -343,7 +344,7 @@ impl Complex { } } - pub(crate) fn tan(self, int: &I) -> Result, FendError> { + pub(crate) fn tan(self, int: &I) -> FendCoreResult> { let num = self.clone().sin(int)?; let den = self.cos(int)?; num.div(den, int) @@ -351,7 +352,7 @@ impl Complex { /// Calculates ln(i * z + sqrt(1 - z^2)) /// This is used to implement asin and acos for all complex numbers - fn asin_ln(self, int: &I) -> Result, FendError> { + fn asin_ln(self, int: &I) -> FendCoreResult> { let half = Exact::new(Self::from(1), true).div(Exact::new(Self::from(2), true), int)?; let exact = Exact::new(self, true); let i = Exact::new(Self::i(), true); @@ -365,7 +366,7 @@ impl Complex { .try_and_then(|x| x.ln(int)) } - pub(crate) fn asin(self, int: &I) -> Result { + pub(crate) fn asin(self, int: &I) -> FendCoreResult { // Real asin is defined for -1 <= x <= 1 if self.imag.is_zero() && Real::from(1).neg() < self.real && self.real < 1.into() { Ok(Self::from(self.real.asin(int)?)) @@ -379,7 +380,7 @@ impl Complex { } } - pub(crate) fn acos(self, int: &I) -> Result { + pub(crate) fn acos(self, int: &I) -> FendCoreResult { // Real acos is defined for -1 <= x <= 1 if self.imag.is_zero() && Real::from(1).neg() < self.real && self.real < 1.into() { Ok(Self::from(self.real.acos(int)?)) @@ -395,7 +396,7 @@ impl Complex { } } - pub(crate) fn atan(self, int: &I) -> Result { + pub(crate) fn atan(self, int: &I) -> FendCoreResult { // Real atan is defined for all real numbers if self.imag.is_zero() { Ok(Self::from(self.real.atan(int)?)) @@ -419,7 +420,7 @@ impl Complex { } } - pub(crate) fn sinh(self, int: &I) -> Result { + pub(crate) fn sinh(self, int: &I) -> FendCoreResult { if self.imag.is_zero() { Ok(Self::from(self.real.sinh(int)?)) } else { @@ -436,7 +437,7 @@ impl Complex { } } - pub(crate) fn cosh(self, int: &I) -> Result { + pub(crate) fn cosh(self, int: &I) -> FendCoreResult { if self.imag.is_zero() { Ok(Self::from(self.real.cosh(int)?)) } else { @@ -453,7 +454,7 @@ impl Complex { } } - pub(crate) fn tanh(self, int: &I) -> Result { + pub(crate) fn tanh(self, int: &I) -> FendCoreResult { if self.imag.is_zero() { Ok(Self::from(self.real.tanh(int)?)) } else { @@ -464,7 +465,7 @@ impl Complex { } } - pub(crate) fn asinh(self, int: &I) -> Result { + pub(crate) fn asinh(self, int: &I) -> FendCoreResult { // Real asinh is defined for all real numbers if self.imag.is_zero() { Ok(Self::from(self.real.asinh(int)?)) @@ -483,7 +484,7 @@ impl Complex { } } - pub(crate) fn acosh(self, int: &I) -> Result { + pub(crate) fn acosh(self, int: &I) -> FendCoreResult { // Real acosh is defined for x >= 1 if self.imag.is_zero() && self.real >= 1.into() { Ok(Self::from(self.real.acosh(int)?)) @@ -502,7 +503,7 @@ impl Complex { } } - pub(crate) fn atanh(self, int: &I) -> Result { + pub(crate) fn atanh(self, int: &I) -> FendCoreResult { // Real atanh is defined for -1 < x < 1 // Undefined for x = 1, -1 if self.imag.is_zero() && Real::from(1).neg() <= self.real && self.real <= 1.into() { @@ -524,7 +525,7 @@ impl Complex { } } - pub(crate) fn ln(self, int: &I) -> Result, FendError> { + pub(crate) fn ln(self, int: &I) -> FendCoreResult> { if self.imag.is_zero() && self.real > 0.into() { Ok(self.real.ln(int)?.apply(Self::from)) } else { @@ -543,21 +544,21 @@ impl Complex { } } - pub(crate) fn log(self, base: Self, int: &I) -> Result { + pub(crate) fn log(self, base: Self, int: &I) -> FendCoreResult { // log_n(z) = ln(z) / ln(n) let ln = self.ln(int)?; let ln2 = base.ln(int)?; Ok(ln.div(ln2, int)?.value) } - pub(crate) fn log2(self, int: &I) -> Result { + pub(crate) fn log2(self, int: &I) -> FendCoreResult { if self.imag.is_zero() && self.real > 0.into() { Ok(Self::from(self.real.log2(int)?)) } else { self.log(Self::from(2), int) } } - pub(crate) fn log10(self, int: &I) -> Result { + pub(crate) fn log10(self, int: &I) -> FendCoreResult { if self.imag.is_zero() && self.real > 0.into() { Ok(Self::from(self.real.log10(int)?)) } else { @@ -569,7 +570,7 @@ impl Complex { self.real.is_definitely_one() && self.imag.is_definitely_zero() } - pub(crate) fn modulo(self, rhs: Self, int: &I) -> Result { + pub(crate) fn modulo(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.expect_real()?.modulo(rhs.expect_real()?, int)?, )) @@ -580,7 +581,7 @@ impl Complex { rhs: Self, op: crate::ast::BitwiseBop, int: &I, - ) -> Result { + ) -> FendCoreResult { Ok(Self::from(self.expect_real()?.bitwise( rhs.expect_real()?, op, @@ -588,13 +589,13 @@ impl Complex { )?)) } - pub(crate) fn combination(self, rhs: Self, int: &I) -> Result { + pub(crate) fn combination(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.expect_real()?.combination(rhs.expect_real()?, int)?, )) } - pub(crate) fn permutation(self, rhs: Self, int: &I) -> Result { + pub(crate) fn permutation(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.expect_real()?.permutation(rhs.expect_real()?, int)?, )) @@ -602,7 +603,7 @@ impl Complex { } impl Exact { - pub(crate) fn add(self, rhs: Self, int: &I) -> Result { + pub(crate) fn add(self, rhs: Self, int: &I) -> FendCoreResult { let (self_real, self_imag) = self.apply(|x| (x.real, x.imag)).pair(); let (rhs_real, rhs_imag) = rhs.apply(|x| (x.real, x.imag)).pair(); let real = self_real.add(rhs_real, int)?; @@ -616,7 +617,7 @@ impl Exact { )) } - pub(crate) fn mul(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn mul(self, rhs: &Self, int: &I) -> FendCoreResult { // (a + bi) * (c + di) // => ac + bci + adi - bd // => (ac - bd) + (bc + ad)i @@ -638,7 +639,7 @@ impl Exact { )) } - pub(crate) fn div(self, rhs: Self, int: &I) -> Result { + pub(crate) fn div(self, rhs: Self, int: &I) -> FendCoreResult { // (u + vi) / (x + yi) = (1/(x^2 + y^2)) * ((ux + vy) + (vx - uy)i) let (u, v) = self.apply(|x| (x.real, x.imag)).pair(); let (x, y) = rhs.apply(|x| (x.real, x.imag)).pair(); diff --git a/core/src/num/continued_fraction.rs b/core/src/num/continued_fraction.rs index 2874d6d0..b981a04c 100644 --- a/core/src/num/continued_fraction.rs +++ b/core/src/num/continued_fraction.rs @@ -10,6 +10,7 @@ use crate::format::Format; use crate::interrupt::Never; use crate::num::bigrat::sign::Sign; use crate::num::biguint::BigUint; +use crate::result::FendCoreResult; use crate::Interrupt; use std::hash::Hash; use std::rc::Rc; @@ -42,7 +43,7 @@ impl ContinuedFraction { } } - pub(crate) fn try_as_usize(&self, int: &I) -> Result { + pub(crate) fn try_as_usize(&self, int: &I) -> FendCoreResult { if self.actual_integer_sign() == Sign::Negative { return Err(FendError::NegativeNumbersNotAllowed); } @@ -96,7 +97,7 @@ impl ContinuedFraction { self.integer == 0.into() && (self.fraction)().next().is_none() } - pub(crate) fn invert(self) -> Result { + pub(crate) fn invert(self) -> FendCoreResult { if self.actual_integer_sign() == Sign::Negative { return Err(FendError::NegativeNumbersNotAllowed); } @@ -126,7 +127,7 @@ impl ContinuedFraction { args: [impl Into; 4], f: fn() -> Option, int: &I, - ) -> Result { + ) -> FendCoreResult { if self.actual_integer_sign() == Sign::Negative { return Err(FendError::NegativeNumbersNotAllowed); } @@ -165,7 +166,7 @@ impl ContinuedFraction { x: Self, y: Self, args: [impl Into; 8], - ) -> Result { + ) -> FendCoreResult { if x.actual_integer_sign() == Sign::Negative || y.actual_integer_sign() == Sign::Negative { return Err(FendError::NegativeNumbersNotAllowed); } @@ -208,22 +209,22 @@ impl ContinuedFraction { }) } - pub(crate) fn add(&self, other: &Self, int: &I) -> Result { + pub(crate) fn add(&self, other: &Self, int: &I) -> FendCoreResult { Self::bihomographic(self.clone(), other.clone(), [0, 1, 1, 0, 0, 0, 0, 1]) } - pub(crate) fn mul(&self, other: &Self, int: &I) -> Result { + pub(crate) fn mul(&self, other: &Self, int: &I) -> FendCoreResult { Self::bihomographic(self.clone(), other.clone(), [1, 0, 0, 0, 0, 0, 0, 1]) } - pub(crate) fn div(&self, other: &Self, int: &I) -> Result { + pub(crate) fn div(&self, other: &Self, int: &I) -> FendCoreResult { if other.is_zero() { return Err(FendError::DivideByZero); } self.clone().invert()?.mul(&other.clone().invert()?, int) } - pub(crate) fn modulo(&self, other: &Self, int: &I) -> Result { + pub(crate) fn modulo(&self, other: &Self, int: &I) -> FendCoreResult { if other.is_zero() { return Err(FendError::ModuloByZero); } @@ -237,14 +238,14 @@ impl ContinuedFraction { Ok(Self::from(self.integer.divmod(&other.integer, int)?.1)) } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { self.integer_sign.serialize(write)?; self.integer.serialize(write)?; // TODO serialize fraction Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { integer_sign: Sign::deserialize(read)?, integer: BigUint::deserialize(read)?, @@ -661,7 +662,7 @@ fn format_as_integer( use_parens_if_product: bool, sf_limit: Option, int: &I, -) -> Result, FendError> { +) -> FendCoreResult> { let (ty, exact) = if !term.is_empty() && !base.has_prefix() && num == &1.into() { ( FormattedContinuedFractionType::Integer(None, false, term, false), @@ -698,7 +699,7 @@ impl Format for ContinuedFraction { &self, params: &Self::Params, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let sign = self.actual_integer_sign(); // try as integer if possible diff --git a/core/src/num/dist.rs b/core/src/num/dist.rs index 94a06b75..0e91de32 100644 --- a/core/src/num/dist.rs +++ b/core/src/num/dist.rs @@ -2,7 +2,8 @@ use crate::error::{FendError, Interrupt}; use crate::interrupt::test_int; use crate::num::bigrat::BigRat; use crate::num::complex::{self, Complex}; -use crate::serialize::{deserialize_usize, serialize_usize}; +use crate::result::FendCoreResult; +use crate::serialize::{Deserialize, Serialize}; use std::cmp::Ordering; use std::collections::HashMap; use std::fmt::Write; @@ -19,8 +20,8 @@ pub(crate) struct Dist { } impl Dist { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_usize(self.parts.len(), write)?; + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.parts.len().serialize(write)?; for (a, b) in &self.parts { a.serialize(write)?; b.serialize(write)?; @@ -28,8 +29,8 @@ impl Dist { Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - let len = deserialize_usize(read)?; + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let len = usize::deserialize(read)?; let mut hashmap = HashMap::with_capacity(len); for _ in 0..len { let k = Complex::deserialize(read)?; @@ -39,7 +40,7 @@ impl Dist { Ok(Self { parts: hashmap }) } - pub(crate) fn one_point(self) -> Result { + pub(crate) fn one_point(self) -> FendCoreResult { if self.parts.len() == 1 { Ok(self.parts.into_iter().next().unwrap().0) } else { @@ -47,7 +48,7 @@ impl Dist { } } - pub(crate) fn one_point_ref(&self) -> Result<&Complex, FendError> { + pub(crate) fn one_point_ref(&self) -> FendCoreResult<&Complex> { if self.parts.len() == 1 { Ok(self.parts.iter().next().unwrap().0) } else { @@ -55,11 +56,7 @@ impl Dist { } } - pub(crate) fn new_die( - count: u32, - faces: u32, - int: &I, - ) -> Result { + pub(crate) fn new_die(count: u32, faces: u32, int: &I) -> FendCoreResult { assert!(count != 0); assert!(faces != 0); if count > 1 { @@ -90,7 +87,7 @@ impl Dist { self, ctx: &crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { if self.parts.len() == 1 { return Ok(self); } @@ -120,7 +117,7 @@ impl Dist { out: &mut String, ctx: &crate::Context, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { if self.parts.len() == 1 { let res = self.parts.iter().next().unwrap().0.format( exact, @@ -184,9 +181,9 @@ impl Dist { fn bop( self, rhs: &Self, - mut f: impl FnMut(&Complex, &Complex, &I) -> Result, + mut f: impl FnMut(&Complex, &Complex, &I) -> FendCoreResult, int: &I, - ) -> Result { + ) -> FendCoreResult { let mut result = HashMap::::new(); for (n1, p1) in &self.parts { for (n2, p2) in &rhs.parts { @@ -204,7 +201,7 @@ impl Dist { } impl Exact { - pub(crate) fn add(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn add(self, rhs: &Self, int: &I) -> FendCoreResult { let self_exact = self.exact; let rhs_exact = rhs.exact; let mut exact = true; @@ -223,7 +220,7 @@ impl Exact { )) } - pub(crate) fn mul(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn mul(self, rhs: &Self, int: &I) -> FendCoreResult { let self_exact = self.exact; let rhs_exact = rhs.exact; let mut exact = true; @@ -242,7 +239,7 @@ impl Exact { )) } - pub(crate) fn div(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn div(self, rhs: &Self, int: &I) -> FendCoreResult { let self_exact = self.exact; let rhs_exact = rhs.exact; let mut exact = true; diff --git a/core/src/num/formatting_style.rs b/core/src/num/formatting_style.rs index 01369910..45638c2f 100644 --- a/core/src/num/formatting_style.rs +++ b/core/src/num/formatting_style.rs @@ -2,7 +2,8 @@ use std::{fmt, io}; use crate::{ error::FendError, - serialize::{deserialize_u8, deserialize_usize, serialize_u8, serialize_usize}, + result::FendCoreResult, + serialize::{Deserialize, Serialize}, }; #[derive(PartialEq, Eq, Clone, Copy, Default)] @@ -57,33 +58,33 @@ impl fmt::Debug for FormattingStyle { } impl FormattingStyle { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { match self { - Self::ImproperFraction => serialize_u8(1, write)?, - Self::MixedFraction => serialize_u8(2, write)?, - Self::ExactFloat => serialize_u8(3, write)?, - Self::Exact => serialize_u8(4, write)?, + Self::ImproperFraction => 1u8.serialize(write)?, + Self::MixedFraction => 2u8.serialize(write)?, + Self::ExactFloat => 3u8.serialize(write)?, + Self::Exact => 4u8.serialize(write)?, Self::DecimalPlaces(d) => { - serialize_u8(5, write)?; - serialize_usize(*d, write)?; + 5u8.serialize(write)?; + d.serialize(write)?; } Self::SignificantFigures(s) => { - serialize_u8(6, write)?; - serialize_usize(*s, write)?; + 6u8.serialize(write)?; + s.serialize(write)?; } - Self::Auto => serialize_u8(7, write)?, + Self::Auto => 7u8.serialize(write)?, } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(match u8::deserialize(read)? { 1 => Self::ImproperFraction, 2 => Self::MixedFraction, 3 => Self::ExactFloat, 4 => Self::Exact, - 5 => Self::DecimalPlaces(deserialize_usize(read)?), - 6 => Self::SignificantFigures(deserialize_usize(read)?), + 5 => Self::DecimalPlaces(usize::deserialize(read)?), + 6 => Self::SignificantFigures(usize::deserialize(read)?), 7 => Self::Auto, _ => return Err(FendError::DeserializationError), }) diff --git a/core/src/num/real.rs b/core/src/num/real.rs index 79cc39fd..45c64640 100644 --- a/core/src/num/real.rs +++ b/core/src/num/real.rs @@ -3,7 +3,8 @@ use crate::format::Format; use crate::num::bigrat::{BigRat, FormattedBigRat}; use crate::num::Exact; use crate::num::{Base, FormattingStyle}; -use crate::serialize::{deserialize_u8, serialize_u8}; +use crate::result::FendCoreResult; +use crate::serialize::{Deserialize, Serialize}; use std::cmp::Ordering; use std::ops::Neg; use std::{fmt, hash, io}; @@ -75,23 +76,23 @@ impl hash::Hash for Real { } impl Real { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { match &self.pattern { Pattern::Simple(s) => { - serialize_u8(1, write)?; + 1u8.serialize(write)?; s.serialize(write)?; } Pattern::Pi(n) => { - serialize_u8(2, write)?; + 2u8.serialize(write)?; n.serialize(write)?; } } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { - pattern: match deserialize_u8(read)? { + pattern: match u8::deserialize(read)? { 1 => Pattern::Simple(BigRat::deserialize(read)?), 2 => Pattern::Pi(BigRat::deserialize(read)?), _ => return Err(FendError::DeserializationError), @@ -106,7 +107,7 @@ impl Real { } } - fn approximate(self, int: &I) -> Result { + fn approximate(self, int: &I) -> FendCoreResult { match self.pattern { Pattern::Simple(s) => Ok(s), Pattern::Pi(n) => { @@ -118,7 +119,7 @@ impl Real { } } - pub(crate) fn try_as_i64(self, int: &I) -> Result { + pub(crate) fn try_as_i64(self, int: &I) -> FendCoreResult { match self.pattern { Pattern::Simple(s) => s.try_as_i64(int), Pattern::Pi(n) => { @@ -131,7 +132,7 @@ impl Real { } } - pub(crate) fn try_as_usize(self, int: &I) -> Result { + pub(crate) fn try_as_usize(self, int: &I) -> FendCoreResult { match self.pattern { Pattern::Simple(s) => s.try_as_usize(int), Pattern::Pi(n) => { @@ -145,7 +146,7 @@ impl Real { } // sin works for all real numbers - pub(crate) fn sin(self, int: &I) -> Result, FendError> { + pub(crate) fn sin(self, int: &I) -> FendCoreResult> { Ok(match self.pattern { Pattern::Simple(s) => s.sin(int)?.apply(Self::from), Pattern::Pi(n) => { @@ -180,68 +181,68 @@ impl Real { }) } - pub(crate) fn cos(self, int: &I) -> Result, FendError> { + pub(crate) fn cos(self, int: &I) -> FendCoreResult> { // cos(x) = sin(x + pi/2) let half_pi = Exact::new(Self::pi(), true).div(&Exact::new(Self::from(2), true), int)?; Exact::new(self, true).add(half_pi, int)?.value.sin(int) } - pub(crate) fn asin(self, int: &I) -> Result { + pub(crate) fn asin(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.asin(int)?)) } - pub(crate) fn acos(self, int: &I) -> Result { + pub(crate) fn acos(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.acos(int)?)) } - pub(crate) fn atan(self, int: &I) -> Result { + pub(crate) fn atan(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.atan(int)?)) } - pub(crate) fn atan2(self, rhs: Self, int: &I) -> Result { + pub(crate) fn atan2(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.approximate(int)?.atan2(rhs.approximate(int)?, int)?, )) } - pub(crate) fn sinh(self, int: &I) -> Result { + pub(crate) fn sinh(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.sinh(int)?)) } - pub(crate) fn cosh(self, int: &I) -> Result { + pub(crate) fn cosh(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.cosh(int)?)) } - pub(crate) fn tanh(self, int: &I) -> Result { + pub(crate) fn tanh(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.tanh(int)?)) } - pub(crate) fn asinh(self, int: &I) -> Result { + pub(crate) fn asinh(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.asinh(int)?)) } - pub(crate) fn acosh(self, int: &I) -> Result { + pub(crate) fn acosh(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.acosh(int)?)) } - pub(crate) fn atanh(self, int: &I) -> Result { + pub(crate) fn atanh(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.atanh(int)?)) } // For all logs: value must be greater than 0 - pub(crate) fn ln(self, int: &I) -> Result, FendError> { + pub(crate) fn ln(self, int: &I) -> FendCoreResult> { Ok(self.approximate(int)?.ln(int)?.apply(Self::from)) } - pub(crate) fn log2(self, int: &I) -> Result { + pub(crate) fn log2(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.log2(int)?)) } - pub(crate) fn log10(self, int: &I) -> Result { + pub(crate) fn log10(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.log10(int)?)) } - pub(crate) fn factorial(self, int: &I) -> Result { + pub(crate) fn factorial(self, int: &I) -> FendCoreResult { Ok(Self::from(self.approximate(int)?.factorial(int)?)) } @@ -252,7 +253,7 @@ impl Real { imag: bool, use_parens_if_fraction: bool, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let mut pi = false; if style == FormattingStyle::Exact && !self.is_zero() { if let Pattern::Pi(_) = self.pattern { @@ -302,11 +303,11 @@ impl Real { )) } - pub(crate) fn exp(self, int: &I) -> Result, FendError> { + pub(crate) fn exp(self, int: &I) -> FendCoreResult> { Ok(self.approximate(int)?.exp(int)?.apply(Self::from)) } - pub(crate) fn pow(self, rhs: Self, int: &I) -> Result, FendError> { + pub(crate) fn pow(self, rhs: Self, int: &I) -> FendCoreResult> { // x^1 == x if let Pattern::Simple(n) = &rhs.pattern { if n == &1.into() { @@ -334,7 +335,7 @@ impl Real { } } - pub(crate) fn root_n(self, n: &Self, int: &I) -> Result, FendError> { + pub(crate) fn root_n(self, n: &Self, int: &I) -> FendCoreResult> { // TODO: Combining these match blocks is not currently possible because // 'binding by-move and by-ref in the same pattern is unstable' // https://github.com/rust-lang/rust/pull/76119 @@ -379,14 +380,14 @@ impl Real { } } - pub(crate) fn expect_rational(self) -> Result { + pub(crate) fn expect_rational(self) -> FendCoreResult { match self.pattern { Pattern::Simple(a) => Ok(a), Pattern::Pi(_) => Err(FendError::ExpectedARationalNumber), } } - pub(crate) fn modulo(self, rhs: Self, int: &I) -> Result { + pub(crate) fn modulo(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.expect_rational()? .modulo(rhs.expect_rational()?, int)?, @@ -398,7 +399,7 @@ impl Real { rhs: Self, op: crate::ast::BitwiseBop, int: &I, - ) -> Result { + ) -> FendCoreResult { Ok(Self::from(self.expect_rational()?.bitwise( rhs.expect_rational()?, op, @@ -406,14 +407,14 @@ impl Real { )?)) } - pub(crate) fn combination(self, rhs: Self, int: &I) -> Result { + pub(crate) fn combination(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.expect_rational()? .combination(rhs.expect_rational()?, int)?, )) } - pub(crate) fn permutation(self, rhs: Self, int: &I) -> Result { + pub(crate) fn permutation(self, rhs: Self, int: &I) -> FendCoreResult { Ok(Self::from( self.expect_rational()? .permutation(rhs.expect_rational()?, int)?, @@ -422,7 +423,7 @@ impl Real { } impl Exact { - pub(crate) fn add(self, rhs: Self, int: &I) -> Result { + pub(crate) fn add(self, rhs: Self, int: &I) -> FendCoreResult { if self.exact && self.value.is_zero() { return Ok(rhs); } else if rhs.exact && rhs.value.is_zero() { @@ -449,7 +450,7 @@ impl Exact { ) } - pub(crate) fn mul(self, rhs: Exact<&Real>, int: &I) -> Result { + pub(crate) fn mul(self, rhs: Exact<&Real>, int: &I) -> FendCoreResult { if self.exact && self.value.is_zero() { return Ok(self); } else if rhs.exact && rhs.value.is_zero() { @@ -483,7 +484,7 @@ impl Exact { }) } - pub(crate) fn div(self, rhs: &Self, int: &I) -> Result { + pub(crate) fn div(self, rhs: &Self, int: &I) -> FendCoreResult { if rhs.value.is_zero() { return Err(FendError::DivideByZero); } diff --git a/core/src/num/unit.rs b/core/src/num/unit.rs index a80b9e93..9d34ced7 100644 --- a/core/src/num/unit.rs +++ b/core/src/num/unit.rs @@ -3,8 +3,9 @@ use crate::error::{FendError, Interrupt}; use crate::num::complex::{Complex, UseParentheses}; use crate::num::dist::Dist; use crate::num::{Base, FormattingStyle}; +use crate::result::FendCoreResult; use crate::scope::Scope; -use crate::serialize::{deserialize_bool, deserialize_usize, serialize_bool, serialize_usize}; +use crate::serialize::{Deserialize, Serialize}; use crate::units::{lookup_default_unit, query_unit_static}; use crate::{ast, ident::Ident}; use crate::{Attrs, Span, SpanKind}; @@ -25,6 +26,7 @@ use unit_exponent::UnitExponent; use super::Exact; #[derive(Clone)] +#[allow(clippy::pedantic)] pub(crate) struct Value { value: Dist, unit: Unit, @@ -35,35 +37,35 @@ pub(crate) struct Value { } impl Value { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { self.value.serialize(write)?; self.unit.serialize(write)?; - serialize_bool(self.exact, write)?; + self.exact.serialize(write)?; self.base.serialize(write)?; self.format.serialize(write)?; - serialize_bool(self.simplifiable, write)?; + self.simplifiable.serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { value: Dist::deserialize(read)?, unit: Unit::deserialize(read)?, - exact: deserialize_bool(read)?, + exact: bool::deserialize(read)?, base: Base::deserialize(read)?, format: FormattingStyle::deserialize(read)?, - simplifiable: deserialize_bool(read)?, + simplifiable: bool::deserialize(read)?, }) } - pub(crate) fn try_as_usize(self, int: &I) -> Result { + pub(crate) fn try_as_usize(self, int: &I) -> FendCoreResult { if !self.is_unitless(int)? { return Err(FendError::NumberWithUnitToInt); } self.try_as_usize_unit(int) } - pub(crate) fn try_as_usize_unit(self, int: &I) -> Result { + pub(crate) fn try_as_usize_unit(self, int: &I) -> FendCoreResult { if !self.exact { return Err(FendError::InexactNumberToInt); } @@ -77,7 +79,7 @@ impl Value { singular_name: Cow<'static, str>, plural_name: Cow<'static, str>, int: &I, - ) -> Result { + ) -> FendCoreResult { let (hashmap, scale) = value.unit.to_hashmap_and_scale(int)?; let scale = scale.mul(&Exact::new(value.value.one_point_ref()?.clone(), true), int)?; let resulting_unit = NamedUnit::new( @@ -133,7 +135,7 @@ impl Value { } } - pub(crate) fn factorial(self, int: &I) -> Result { + pub(crate) fn factorial(self, int: &I) -> FendCoreResult { if !self.is_unitless(int)? { return Err(FendError::FactorialUnitless); } @@ -160,7 +162,7 @@ impl Value { } } - pub(crate) fn add(self, rhs: Self, int: &I) -> Result { + pub(crate) fn add(self, rhs: Self, int: &I) -> FendCoreResult { let scale_factor = Unit::compute_scale_factor(&rhs.unit, &self.unit, int)?; let scaled = Exact::new(rhs.value, rhs.exact) .mul(&scale_factor.scale_1.apply(Dist::from), int)? @@ -186,7 +188,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { for (lhs_unit, rhs_unit) in crate::units::IMPLICIT_UNIT_MAP { if self.unit.equal_to(lhs_unit) && rhs.is_unitless(int)? { let inches = @@ -198,7 +200,7 @@ impl Value { Ok(rhs) } - pub(crate) fn convert_to(self, rhs: Self, int: &I) -> Result { + pub(crate) fn convert_to(self, rhs: Self, int: &I) -> FendCoreResult { if rhs.value.one_point()? != 1.into() { return Err(FendError::ConversionRhsNumerical); } @@ -217,7 +219,7 @@ impl Value { }) } - pub(crate) fn sub(self, rhs: Self, int: &I) -> Result { + pub(crate) fn sub(self, rhs: Self, int: &I) -> FendCoreResult { let scale_factor = Unit::compute_scale_factor(&rhs.unit, &self.unit, int)?; let scaled = Exact::new(rhs.value, rhs.exact) .mul(&scale_factor.scale_1.apply(Dist::from), int)? @@ -233,7 +235,7 @@ impl Value { }) } - pub(crate) fn div(self, rhs: Self, int: &I) -> Result { + pub(crate) fn div(self, rhs: Self, int: &I) -> FendCoreResult { let mut components = self.unit.components.clone(); for rhs_component in rhs.unit.components { components.push(UnitExponent::new( @@ -253,7 +255,7 @@ impl Value { }) } - fn modulo(self, rhs: Self, int: &I) -> Result { + fn modulo(self, rhs: Self, int: &I) -> FendCoreResult { if !self.is_unitless(int)? || !rhs.is_unitless(int)? { return Err(FendError::ModuloUnitless); } @@ -271,7 +273,7 @@ impl Value { }) } - fn bitwise(self, rhs: Self, op: BitwiseBop, int: &I) -> Result { + fn bitwise(self, rhs: Self, op: BitwiseBop, int: &I) -> FendCoreResult { if !self.is_unitless(int)? || !rhs.is_unitless(int)? { return Err(FendError::ExpectedAUnitlessNumber); } @@ -289,7 +291,7 @@ impl Value { }) } - pub(crate) fn combination(self, rhs: Self, int: &I) -> Result { + pub(crate) fn combination(self, rhs: Self, int: &I) -> FendCoreResult { if !self.is_unitless(int)? || !rhs.is_unitless(int)? { return Err(FendError::ExpectedAUnitlessNumber); } @@ -307,7 +309,7 @@ impl Value { }) } - pub(crate) fn permutation(self, rhs: Self, int: &I) -> Result { + pub(crate) fn permutation(self, rhs: Self, int: &I) -> FendCoreResult { if !self.is_unitless(int)? || !rhs.is_unitless(int)? { return Err(FendError::ExpectedAUnitlessNumber); } @@ -332,7 +334,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { match op { Bop::Plus => self.add(rhs, int), Bop::ImplicitPlus => { @@ -350,7 +352,7 @@ impl Value { } } - pub(crate) fn is_unitless(&self, int: &I) -> Result { + pub(crate) fn is_unitless(&self, int: &I) -> FendCoreResult { // todo this is broken for unitless components if self.unit.components.is_empty() { return Ok(true); @@ -362,11 +364,11 @@ impl Value { Ok(false) } - pub(crate) fn is_unitless_one(&self, int: &I) -> Result { + pub(crate) fn is_unitless_one(&self, int: &I) -> FendCoreResult { Ok(self.exact && self.value.equals_int(1) && self.is_unitless(int)?) } - pub(crate) fn pow(self, rhs: Self, int: &I) -> Result { + pub(crate) fn pow(self, rhs: Self, int: &I) -> FendCoreResult { if !rhs.is_unitless(int)? { return Err(FendError::ExpUnitless); } @@ -417,7 +419,7 @@ impl Value { } } - pub(crate) fn abs(self, int: &I) -> Result { + pub(crate) fn abs(self, int: &I) -> FendCoreResult { let value = self.value.one_point()?.abs(int)?; Ok(Self { value: Complex::from(value.value).into(), @@ -455,24 +457,20 @@ impl Value { self.value.equals_int(0) } - pub(crate) fn new_die( - count: u32, - faces: u32, - int: &I, - ) -> Result { + pub(crate) fn new_die(count: u32, faces: u32, int: &I) -> FendCoreResult { Ok(Self::new(Dist::new_die(count, faces, int)?, vec![])) } - fn remove_unit_scaling(self, int: &I) -> Result { + fn remove_unit_scaling(self, int: &I) -> FendCoreResult { self.convert_to(Self::unitless(), int) } fn apply_fn_exact( mut self, - f: impl FnOnce(Complex, &I) -> Result, FendError>, + f: impl FnOnce(Complex, &I) -> FendCoreResult>, require_unitless: bool, int: &I, - ) -> Result { + ) -> FendCoreResult { self = self.remove_unit_scaling(int)?; if require_unitless && !self.is_unitless(int)? { return Err(FendError::ExpectedAUnitlessNumber); @@ -490,10 +488,10 @@ impl Value { fn apply_fn( mut self, - f: impl FnOnce(Complex, &I) -> Result, + f: impl FnOnce(Complex, &I) -> FendCoreResult, require_unitless: bool, int: &I, - ) -> Result { + ) -> FendCoreResult { self = self.remove_unit_scaling(int)?; if require_unitless && !self.is_unitless(int)? { return Err(FendError::ExpectedAUnitlessNumber); @@ -512,7 +510,7 @@ impl Value { self, ctx: &crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { Ok(Self { value: self.value.sample(ctx, int)?, ..self @@ -525,7 +523,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { let radians = ast::resolve_identifier(&Ident::new_str("radians"), scope, attrs, context, int)? .expect_num()?; @@ -543,21 +541,21 @@ impl Value { } } - pub(crate) fn real(self) -> Result { + pub(crate) fn real(self) -> FendCoreResult { Ok(Self { value: Complex::from(self.value.one_point()?.real()).into(), ..self }) } - pub(crate) fn imag(self) -> Result { + pub(crate) fn imag(self) -> FendCoreResult { Ok(Self { value: Complex::from(self.value.one_point()?.imag()).into(), ..self }) } - pub(crate) fn arg(self, int: &I) -> Result { + pub(crate) fn arg(self, int: &I) -> FendCoreResult { self.apply_fn_exact( |c, int| c.arg(int).map(|c| c.apply(Complex::from)), false, @@ -565,7 +563,7 @@ impl Value { ) } - pub(crate) fn conjugate(self) -> Result { + pub(crate) fn conjugate(self) -> FendCoreResult { Ok(Self { value: self.value.one_point()?.conjugate().into(), ..self @@ -578,7 +576,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { if let Ok(rad) = self .clone() .convert_angle_to_rad(scope, attrs, context, int) @@ -597,7 +595,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { if let Ok(rad) = self .clone() .convert_angle_to_rad(scope, attrs, context, int) @@ -615,7 +613,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { if let Ok(rad) = self .clone() .convert_angle_to_rad(scope, attrs, context, int) @@ -627,51 +625,51 @@ impl Value { } } - pub(crate) fn asin(self, int: &I) -> Result { + pub(crate) fn asin(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::asin, false, int) } - pub(crate) fn acos(self, int: &I) -> Result { + pub(crate) fn acos(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::acos, false, int) } - pub(crate) fn atan(self, int: &I) -> Result { + pub(crate) fn atan(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::atan, false, int) } - pub(crate) fn sinh(self, int: &I) -> Result { + pub(crate) fn sinh(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::sinh, false, int) } - pub(crate) fn cosh(self, int: &I) -> Result { + pub(crate) fn cosh(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::cosh, false, int) } - pub(crate) fn tanh(self, int: &I) -> Result { + pub(crate) fn tanh(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::tanh, false, int) } - pub(crate) fn asinh(self, int: &I) -> Result { + pub(crate) fn asinh(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::asinh, false, int) } - pub(crate) fn acosh(self, int: &I) -> Result { + pub(crate) fn acosh(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::acosh, false, int) } - pub(crate) fn atanh(self, int: &I) -> Result { + pub(crate) fn atanh(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::atanh, false, int) } - pub(crate) fn ln(self, int: &I) -> Result { + pub(crate) fn ln(self, int: &I) -> FendCoreResult { self.apply_fn_exact(Complex::ln, true, int) } - pub(crate) fn log2(self, int: &I) -> Result { + pub(crate) fn log2(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::log2, true, int) } - pub(crate) fn log10(self, int: &I) -> Result { + pub(crate) fn log10(self, int: &I) -> FendCoreResult { self.apply_fn(Complex::log10, true, int) } @@ -679,7 +677,7 @@ impl Value { &self, ctx: &crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { let use_parentheses = if self.unit.components.is_empty() { UseParentheses::No } else { @@ -714,7 +712,7 @@ impl Value { }) } - pub(crate) fn mul(self, rhs: Self, int: &I) -> Result { + pub(crate) fn mul(self, rhs: Self, int: &I) -> FendCoreResult { let components = [self.unit.components, rhs.unit.components].concat(); let value = Exact::new(self.value, self.exact).mul(&Exact::new(rhs.value, rhs.exact), int)?; @@ -734,7 +732,7 @@ impl Value { attrs: Attrs, ctx: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { if !self.simplifiable { return Ok(self); } @@ -969,16 +967,16 @@ struct ScaleFactor { } impl Unit { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_usize(self.components.len(), write)?; + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.components.len().serialize(write)?; for c in &self.components { c.serialize(write)?; } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - let len = deserialize_usize(read)?; + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let len = usize::deserialize(read)?; let mut cs = Vec::with_capacity(len); for _ in 0..len { cs.push(UnitExponent::deserialize(read)?); @@ -999,7 +997,7 @@ impl Unit { } /// base units with cancelled exponents do not appear in the hashmap - fn to_hashmap_and_scale(&self, int: &I) -> Result { + fn to_hashmap_and_scale(&self, int: &I) -> FendCoreResult { let mut hashmap = HashMap::::new(); let mut scale = Complex::from(1); let mut exact = true; @@ -1012,7 +1010,7 @@ impl Unit { fn reduce_hashmap( hashmap: HashMap, int: &I, - ) -> Result { + ) -> FendCoreResult { if hashmap.len() == 1 && hashmap.get(&BaseUnit::new(Cow::Borrowed("celsius"))) == Some(&1.into()) { @@ -1060,7 +1058,7 @@ impl Unit { fn print_base_units( hash: HashMap, int: &I, - ) -> Result { + ) -> FendCoreResult { let from_base_units: Vec<_> = hash .into_iter() .map(|(base_unit, exponent)| { @@ -1086,7 +1084,7 @@ impl Unit { from: &Self, into: &Self, int: &I, - ) -> Result { + ) -> FendCoreResult { let (hash_a, scale_a) = from.to_hashmap_and_scale(int)?; let (hash_b, scale_b) = into.to_hashmap_and_scale(int)?; let (hash_a, adj_a, offset_a) = Self::reduce_hashmap(hash_a, int)?; @@ -1139,7 +1137,7 @@ impl Unit { format: FormattingStyle, consider_printing_space: bool, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { let mut unit_string = String::new(); if self.components.is_empty() { unit_string.push_str(unitless); diff --git a/core/src/num/unit/base_unit.rs b/core/src/num/unit/base_unit.rs index 94a87e89..320e62ba 100644 --- a/core/src/num/unit/base_unit.rs +++ b/core/src/num/unit/base_unit.rs @@ -1,9 +1,7 @@ use std::{borrow::Cow, fmt, io}; -use crate::{ - error::FendError, - serialize::{deserialize_string, serialize_string}, -}; +use crate::result::FendCoreResult; +use crate::serialize::{Deserialize, Serialize}; /// Represents a base unit, identified solely by its name. The name is not exposed to the user. #[derive(Clone, PartialEq, Eq, Hash)] @@ -32,14 +30,14 @@ impl BaseUnit { self.name.as_ref() } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_string(self.name.as_ref(), write)?; + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.name.as_ref().serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { - name: Cow::Owned(deserialize_string(read)?), + name: Cow::Owned(String::deserialize(read)?), }) } } diff --git a/core/src/num/unit/named_unit.rs b/core/src/num/unit/named_unit.rs index 923b804f..5e4e5564 100644 --- a/core/src/num/unit/named_unit.rs +++ b/core/src/num/unit/named_unit.rs @@ -1,14 +1,9 @@ use std::{borrow::Cow, collections::HashMap, fmt, io}; use super::base_unit::BaseUnit; -use crate::{ - error::FendError, - num::complex::Complex, - serialize::{ - deserialize_bool, deserialize_string, deserialize_usize, serialize_bool, serialize_string, - serialize_usize, - }, -}; +use crate::num::complex::Complex; +use crate::result::FendCoreResult; +use crate::serialize::{Deserialize, Serialize}; /// A named unit, like kilogram, megabyte or percent. #[derive(Clone, Eq, PartialEq)] @@ -40,13 +35,13 @@ impl NamedUnit { } } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_string(self.prefix.as_ref(), write)?; - serialize_string(self.singular_name.as_ref(), write)?; - serialize_string(self.plural_name.as_ref(), write)?; - serialize_bool(self.alias, write)?; + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.prefix.as_ref().serialize(write)?; + self.singular_name.as_ref().serialize(write)?; + self.plural_name.as_ref().serialize(write)?; + self.alias.serialize(write)?; - serialize_usize(self.base_units.len(), write)?; + self.base_units.len().serialize(write)?; for (a, b) in &self.base_units { a.serialize(write)?; b.serialize(write)?; @@ -56,13 +51,13 @@ impl NamedUnit { Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - let prefix = deserialize_string(read)?; - let singular_name = deserialize_string(read)?; - let plural_name = deserialize_string(read)?; - let alias = deserialize_bool(read)?; + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let prefix = String::deserialize(read)?; + let singular_name = String::deserialize(read)?; + let plural_name = String::deserialize(read)?; + let alias = bool::deserialize(read)?; - let len = deserialize_usize(read)?; + let len = usize::deserialize(read)?; let mut hashmap = HashMap::with_capacity(len); for _ in 0..len { let k = BaseUnit::deserialize(read)?; diff --git a/core/src/num/unit/unit_exponent.rs b/core/src/num/unit/unit_exponent.rs index 3a326453..c185f073 100644 --- a/core/src/num/unit/unit_exponent.rs +++ b/core/src/num/unit/unit_exponent.rs @@ -1,14 +1,10 @@ use std::{collections::HashMap, fmt, io}; -use crate::{ - error::FendError, - interrupt::test_int, - num::{ - complex::{self, Complex, UseParentheses}, - Base, Exact, FormattingStyle, - }, - Interrupt, -}; +use crate::interrupt::test_int; +use crate::num::complex::{self, Complex, UseParentheses}; +use crate::num::{Base, Exact, FormattingStyle}; +use crate::result::FendCoreResult; +use crate::Interrupt; use super::{base_unit::BaseUnit, named_unit::NamedUnit}; @@ -26,13 +22,13 @@ impl UnitExponent { } } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { self.unit.serialize(write)?; self.exponent.serialize(write)?; Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { unit: NamedUnit::deserialize(read)?, exponent: Complex::deserialize(read)?, @@ -49,7 +45,7 @@ impl UnitExponent { scale: &mut Complex, exact: &mut bool, int: &I, - ) -> Result<(), FendError> { + ) -> FendCoreResult<()> { test_int(int)?; let overall_exp = &Exact::new(self.exponent.clone(), true); for (base_unit, base_exp) in &self.unit.base_units { @@ -90,7 +86,7 @@ impl UnitExponent { plural: bool, invert_exp: bool, int: &I, - ) -> Result>, FendError> { + ) -> FendCoreResult>> { let (prefix, name) = self.unit.prefix_and_name(plural); let exp = if invert_exp { -self.exponent.clone() diff --git a/core/src/result.rs b/core/src/result.rs new file mode 100644 index 00000000..23dacb68 --- /dev/null +++ b/core/src/result.rs @@ -0,0 +1,3 @@ +use crate::error::FendError; + +pub(crate) type FendCoreResult = Result; diff --git a/core/src/scope.rs b/core/src/scope.rs index 9523dad7..a1dfa8be 100644 --- a/core/src/scope.rs +++ b/core/src/scope.rs @@ -1,6 +1,6 @@ -use crate::error::FendError; use crate::ident::Ident; -use crate::serialize::{deserialize_bool, serialize_bool}; +use crate::result::FendCoreResult; +use crate::serialize::{Deserialize, Serialize}; use crate::value::Value; use crate::Attrs; use crate::{ast::Expr, error::Interrupt}; @@ -19,7 +19,7 @@ impl ScopeValue { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { match self { Self::LazyVariable(expr, scope) => { let value = crate::ast::evaluate(expr.clone(), scope.clone(), attrs, context, int)?; @@ -28,14 +28,14 @@ impl ScopeValue { } } - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { match self { Self::LazyVariable(e, s) => { e.serialize(write)?; match s { - None => serialize_bool(false, write)?, + None => false.serialize(write)?, Some(s) => { - serialize_bool(true, write)?; + true.serialize(write)?; s.serialize(write)?; } } @@ -44,9 +44,9 @@ impl ScopeValue { Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self::LazyVariable(Expr::deserialize(read)?, { - if deserialize_bool(read)? { + if bool::deserialize(read)? { None } else { Some(Arc::new(Scope::deserialize(read)?)) @@ -63,25 +63,25 @@ pub(crate) struct Scope { } impl Scope { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { self.ident.serialize(write)?; self.value.serialize(write)?; match &self.inner { - None => serialize_bool(false, write)?, + None => false.serialize(write)?, Some(s) => { - serialize_bool(true, write)?; + true.serialize(write)?; s.serialize(write)?; } } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { Ok(Self { ident: Ident::deserialize(read)?, value: ScopeValue::deserialize(read)?, inner: { - if deserialize_bool(read)? { + if bool::deserialize(read)? { None } else { Some(Arc::new(Self::deserialize(read)?)) @@ -113,7 +113,7 @@ impl Scope { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result, FendError> { + ) -> FendCoreResult> { if self.ident.as_str() == ident.as_str() { let value = self.value.eval(attrs, context, int)?; Ok(Some(value)) diff --git a/core/src/serialize.rs b/core/src/serialize.rs index f8dc99ed..f6e787f1 100644 --- a/core/src/serialize.rs +++ b/core/src/serialize.rs @@ -1,85 +1,162 @@ -use crate::error::FendError; +use crate::{error::FendError, result::FendCoreResult}; use std::io; -/* - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { - Ok(()) - } - - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - } -*/ - -pub(crate) fn serialize_u8(value: u8, write: &mut impl io::Write) -> io::Result<()> { - write.write_all(&[value]) +pub(crate) trait Serialize +where + Self: Sized, +{ + fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()>; } -pub(crate) fn deserialize_u8(read: &mut impl io::Read) -> io::Result { - let mut buf = [0; 1]; - read.read_exact(&mut buf[..])?; - Ok(buf[0]) +pub(crate) trait Deserialize +where + Self: Sized, +{ + fn deserialize(read: &mut impl io::Read) -> FendCoreResult; } -pub(crate) fn serialize_i32(value: i32, write: &mut impl io::Write) -> io::Result<()> { - write.write_all(&value.to_be_bytes()) +macro_rules! impl_serde { + ($($typ: ty)+) => { + $( + impl Serialize for $typ { + fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + Ok(write.write_all(&self.to_be_bytes())?) + } + } + impl Deserialize for $typ { + fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let mut buf = [0; std::mem::size_of::<$typ>()]; + read.read_exact(&mut buf[..])?; + Ok(<$typ>::from_be_bytes(buf)) + } + } + ) + + }; } -pub(crate) fn deserialize_i32(read: &mut impl io::Read) -> io::Result { - let mut buf = [0; 4]; - read.read_exact(&mut buf[..])?; - Ok(i32::from_be_bytes(buf)) -} - -pub(crate) fn serialize_u64(value: u64, write: &mut impl io::Write) -> io::Result<()> { - write.write_all(&value.to_be_bytes()) -} +impl_serde!(u8 i32 u64 usize); -pub(crate) fn deserialize_u64(read: &mut impl io::Read) -> io::Result { - let mut buf = [0; 8]; - read.read_exact(&mut buf[..])?; - Ok(u64::from_be_bytes(buf)) +impl Serialize for &str { + fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.len().serialize(write)?; + self.as_bytes() + .iter() + .try_for_each(|&bit| bit.serialize(write))?; + Ok(()) + } } -pub(crate) fn serialize_usize(value: usize, write: &mut impl io::Write) -> io::Result<()> { - write.write_all(&value.to_be_bytes()) +impl Deserialize for String { + fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let len = usize::deserialize(read)?; + let mut buf = Vec::with_capacity(len); + for _ in 0..len { + buf.push(u8::deserialize(read)?); + } + match Self::from_utf8(buf) { + Ok(string) => Ok(string), + Err(_) => Err(FendError::DeserializationError), + } + } } -pub(crate) fn deserialize_usize(read: &mut impl io::Read) -> io::Result { - let mut buf = [0; std::mem::size_of::()]; - read.read_exact(&mut buf[..])?; - Ok(usize::from_be_bytes(buf)) +impl Serialize for bool { + fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { + Ok(write.write_all(&[u8::from(*self)])?) + } } -pub(crate) fn serialize_string(value: &str, write: &mut impl io::Write) -> io::Result<()> { - serialize_usize(value.len(), write)?; - for &b in value.as_bytes() { - serialize_u8(b, write)?; +impl Deserialize for bool { + fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + let mut buf = [0; 1]; + read.read_exact(&mut buf[..])?; + match buf[0] { + 0 => Ok(false), + 1 => Ok(true), + _ => Err(FendError::DeserializationError), + } } - Ok(()) } -pub(crate) fn deserialize_string(read: &mut impl io::Read) -> Result { - let len = deserialize_usize(read)?; - let mut buf = Vec::with_capacity(len); - for _ in 0..len { - buf.push(deserialize_u8(read)?); +/* + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + Ok(()) } - match String::from_utf8(buf) { - Ok(string) => Ok(string), - Err(_) => Err(FendError::DeserializationError), + + pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { } -} +*/ -pub(crate) fn serialize_bool(value: bool, write: &mut impl io::Write) -> io::Result<()> { - write.write_all(&[u8::from(value)]) -} +// pub(crate) fn serialize_u8(value: u8, write: &mut impl io::Write) -> io::Result<()> { +// write.write_all(&[value]) +// } -pub(crate) fn deserialize_bool(read: &mut impl io::Read) -> Result { - let mut buf = [0; 1]; - read.read_exact(&mut buf[..])?; - match buf[0] { - 0 => Ok(false), - 1 => Ok(true), - _ => Err(FendError::DeserializationError), - } -} +// pub(crate) fn deserialize_u8(read: &mut impl io::Read) -> io::Result { +// let mut buf = [0; 1]; +// read.read_exact(&mut buf[..])?; +// Ok(u8::from_be_bytes(buf)) +// } + +// pub(crate) fn serialize_i32(value: i32, write: &mut impl io::Write) -> io::Result<()> { +// write.write_all(&value.to_be_bytes()) +// } + +// pub(crate) fn deserialize_i32(read: &mut impl io::Read) -> io::Result { +// let mut buf = [0; 4]; +// read.read_exact(&mut buf[..])?; +// Ok(i32::from_be_bytes(buf)) +// } + +// pub(crate) fn serialize_u64(value: u64, write: &mut impl io::Write) -> io::Result<()> { +// write.write_all(&value.to_be_bytes()) +// } + +// pub(crate) fn deserialize_u64(read: &mut impl io::Read) -> io::Result { +// let mut buf = [0; 8]; +// read.read_exact(&mut buf[..])?; +// Ok(u64::from_be_bytes(buf)) +// } + +// pub(crate) fn serialize_usize(value: usize, write: &mut impl io::Write) -> io::Result<()> { +// write.write_all(&value.to_be_bytes()) +// } + +// pub(crate) fn deserialize_usize(read: &mut impl io::Read) -> io::Result { +// let mut buf = [0; std::mem::size_of::()]; +// read.read_exact(&mut buf[..])?; +// Ok(usize::from_be_bytes(buf)) +// } + +// pub(crate) fn serialize_string(value: &str, write: &mut impl io::Write) -> io::Result<()> { +// serialize_usize(value.len(), write)?; +// for &b in value.as_bytes() { +// serialize_u8(b, write)?; +// } +// Ok(()) +// } + +// pub(crate) fn deserialize_string(read: &mut impl io::Read) -> Result { +// let len = deserialize_usize(read)?; +// let mut buf = Vec::with_capacity(len); +// for _ in 0..len { +// buf.push(deserialize_u8(read)?); +// } +// match String::from_utf8(buf) { +// Ok(string) => Ok(string), +// Err(_) => Err(FendError::DeserializationError), +// } +// } + +// pub(crate) fn serialize_bool(value: bool, write: &mut impl io::Write) -> io::Result<()> { +// write.write_all(&[u8::from(value)]) +// } + +// pub(crate) fn deserialize_bool(read: &mut impl io::Read) -> Result { +// let mut buf = [0; 1]; +// read.read_exact(&mut buf[..])?; +// match buf[0] { +// 0 => Ok(false), +// 1 => Ok(true), +// _ => Err(FendError::DeserializationError), +// } +// } diff --git a/core/src/units.rs b/core/src/units.rs index 898a207a..0265d915 100644 --- a/core/src/units.rs +++ b/core/src/units.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use crate::error::{FendError, Interrupt}; use crate::eval::evaluate_to_value; use crate::num::Number; +use crate::result::FendCoreResult; use crate::value::Value; use crate::Attrs; @@ -34,7 +35,7 @@ fn expr_unit( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { let (singular, plural, definition) = unit_def; let mut definition = definition.trim(); if definition == "$CURRENCY" { @@ -138,11 +139,7 @@ fn expr_unit( }) } -fn construct_prefixed_unit( - a: UnitDef, - b: UnitDef, - int: &I, -) -> Result { +fn construct_prefixed_unit(a: UnitDef, b: UnitDef, int: &I) -> FendCoreResult { let product = a.value.expect_num()?.mul(b.value.expect_num()?, int)?; assert_eq!(a.singular, a.plural); let unit = Number::create_unit_value_from_value( @@ -156,7 +153,7 @@ pub(crate) fn query_unit( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { if ident.starts_with('\'') && ident.ends_with('\'') && ident.len() >= 3 { let ident = ident.split_at(1).1; let ident = ident.split_at(ident.len() - 1).0; @@ -173,7 +170,7 @@ pub(crate) fn query_unit_static( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { match query_unit_case_sensitive(ident, true, attrs, context, int) { Err(FendError::IdentifierNotFound(_)) => (), Err(e) => return Err(e), @@ -190,7 +187,7 @@ fn query_unit_case_sensitive( attrs: Attrs, context: &mut crate::Context, int: &I, -) -> Result { +) -> FendCoreResult { match query_unit_internal(ident, false, case_sensitive, true, context) { Err(FendError::IdentifierNotFound(_)) => (), Err(e) => return Err(e), @@ -241,7 +238,7 @@ fn query_unit_internal( case_sensitive: bool, whole_unit: bool, context: &mut crate::Context, -) -> Result<(Cow<'static, str>, Cow<'static, str>, Cow<'static, str>), FendError> { +) -> FendCoreResult<(Cow<'static, str>, Cow<'static, str>, Cow<'static, str>)> { if !short_prefixes { for (s, p, d) in &context.custom_units { let p = if p.is_empty() { s } else { p }; diff --git a/core/src/value.rs b/core/src/value.rs index 3d2a8852..ca261330 100644 --- a/core/src/value.rs +++ b/core/src/value.rs @@ -2,11 +2,9 @@ use crate::ast::Bop; use crate::date::{Date, DayOfWeek, Month}; use crate::error::{FendError, Interrupt}; use crate::num::{Base, FormattingStyle, Number}; +use crate::result::FendCoreResult; use crate::scope::Scope; -use crate::serialize::{ - deserialize_bool, deserialize_string, deserialize_u8, deserialize_usize, serialize_bool, - serialize_string, serialize_u8, serialize_usize, -}; +use crate::serialize::{Deserialize, Serialize}; use crate::{ast::Expr, ident::Ident}; use crate::{date, Attrs, Span, SpanKind}; use std::borrow::Cow; @@ -46,73 +44,73 @@ pub(crate) enum ApplyMulHandling { } impl Value { - pub(crate) fn serialize(&self, write: &mut impl io::Write) -> Result<(), FendError> { + pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FendCoreResult<()> { match self { Self::Num(n) => { - serialize_u8(0, write)?; + 0u8.serialize(write)?; n.serialize(write)?; } Self::BuiltInFunction(f) => { - serialize_u8(1, write)?; + 1u8.serialize(write)?; f.serialize(write)?; } Self::Format(f) => { - serialize_u8(2, write)?; + 2u8.serialize(write)?; f.serialize(write)?; } - Self::Dp => serialize_u8(3, write)?, - Self::Sf => serialize_u8(4, write)?, + Self::Dp => 3u8.serialize(write)?, + Self::Sf => 4u8.serialize(write)?, Self::Base(b) => { - serialize_u8(5, write)?; + 5u8.serialize(write)?; b.serialize(write)?; } Self::Fn(i, e, s) => { - serialize_u8(6, write)?; + 6u8.serialize(write)?; i.serialize(write)?; e.serialize(write)?; match s { - None => serialize_bool(false, write)?, + None => false.serialize(write)?, Some(s) => { - serialize_bool(true, write)?; + true.serialize(write)?; s.serialize(write)?; } } } Self::Object(o) => { - serialize_u8(7, write)?; - serialize_usize(o.len(), write)?; + 7u8.serialize(write)?; + o.len().serialize(write)?; for (k, v) in o { - serialize_string(k.as_ref(), write)?; + k.as_ref().serialize(write)?; v.serialize(write)?; } } Self::String(s) => { - serialize_u8(8, write)?; - serialize_string(s, write)?; + 8u8.serialize(write)?; + s.as_ref().serialize(write)?; } - Self::Unit => serialize_u8(9, write)?, + Self::Unit => 9u8.serialize(write)?, Self::Bool(b) => { - serialize_u8(10, write)?; - serialize_bool(*b, write)?; + 10u8.serialize(write)?; + b.serialize(write)?; } Self::Month(m) => { - serialize_u8(11, write)?; + 11u8.serialize(write)?; m.serialize(write)?; } Self::DayOfWeek(d) => { - serialize_u8(12, write)?; + 12u8.serialize(write)?; d.serialize(write)?; } Self::Date(d) => { - serialize_u8(13, write)?; + 13u8.serialize(write)?; d.serialize(write)?; } } Ok(()) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Ok(match deserialize_u8(read)? { + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Ok(match u8::deserialize(read)? { 0 => Self::Num(Box::new(Number::deserialize(read)?)), 1 => Self::BuiltInFunction(BuiltInFunction::deserialize(read)?), 2 => Self::Format(FormattingStyle::deserialize(read)?), @@ -122,26 +120,26 @@ impl Value { 6 => Self::Fn( Ident::deserialize(read)?, Box::new(Expr::deserialize(read)?), - if deserialize_bool(read)? { + if bool::deserialize(read)? { Some(Arc::new(Scope::deserialize(read)?)) } else { None }, ), 7 => Self::Object({ - let len = deserialize_usize(read)?; + let len = usize::deserialize(read)?; let mut v = Vec::with_capacity(len); for _ in 0..len { v.push(( - Cow::Owned(deserialize_string(read)?), + Cow::Owned(String::deserialize(read)?), Box::new(Self::deserialize(read)?), )); } v }), - 8 => Self::String(Cow::Owned(deserialize_string(read)?)), + 8 => Self::String(Cow::Owned(String::deserialize(read)?)), 9 => Self::Unit, - 10 => Self::Bool(deserialize_bool(read)?), + 10 => Self::Bool(bool::deserialize(read)?), 11 => Self::Month(Month::deserialize(read)?), 12 => Self::DayOfWeek(DayOfWeek::deserialize(read)?), 13 => Self::Date(Date::deserialize(read)?), @@ -167,7 +165,7 @@ impl Value { } } - fn as_bool(&self) -> Result { + fn as_bool(&self) -> FendCoreResult { if let Self::Bool(b) = self { Ok(*b) } else { @@ -175,7 +173,7 @@ impl Value { } } - pub(crate) fn expect_num(self) -> Result { + pub(crate) fn expect_num(self) -> FendCoreResult { match self { Self::Num(bigrat) => Ok(*bigrat), _ => Err(FendError::ExpectedANumber), @@ -188,10 +186,10 @@ impl Value { pub(crate) fn handle_num( self, - eval_fn: impl FnOnce(Number) -> Result, + eval_fn: impl FnOnce(Number) -> FendCoreResult, lazy_fn: impl FnOnce(Box) -> Expr, scope: Option>, - ) -> Result { + ) -> FendCoreResult { Ok(match self { Self::Num(n) => Self::Num(Box::new(eval_fn(*n)?)), Self::Fn(param, expr, scope) => Self::Fn(param, Box::new(lazy_fn(expr)), scope), @@ -203,11 +201,11 @@ impl Value { pub(crate) fn handle_two_nums) -> Expr, F2: FnOnce(Box) -> Expr>( self, rhs: Self, - eval_fn: impl FnOnce(Number, Number) -> Result, + eval_fn: impl FnOnce(Number, Number) -> FendCoreResult, lazy_fn_lhs: impl FnOnce(Number) -> F1, lazy_fn_rhs: impl FnOnce(Number) -> F2, scope: Option>, - ) -> Result { + ) -> FendCoreResult { Ok(match (self, rhs) { (Self::Num(a), Self::Num(b)) => Self::Num(Box::new(eval_fn(*a, *b)?)), (Self::BuiltInFunction(f), Self::Num(a)) => f.wrap_with_expr(lazy_fn_lhs(*a), scope), @@ -230,7 +228,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { let stringified_self = self.format_to_plain_string(0, attrs, context, int)?; Ok(match self { Self::Num(n) => { @@ -277,7 +275,7 @@ impl Value { attrs: Attrs, context: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { let arg = crate::ast::evaluate(arg, scope.clone(), attrs, context, int)?; Ok(Self::Num(Box::new(match func { BuiltInFunction::Approximately => arg.expect_num()?.make_approximate(), @@ -320,7 +318,7 @@ impl Value { attrs: Attrs, ctx: &mut crate::Context, int: &I, - ) -> Result { + ) -> FendCoreResult { let mut spans = vec![]; self.format(indent, &mut spans, attrs, ctx, int)?; let mut res = String::new(); @@ -337,7 +335,7 @@ impl Value { attrs: Attrs, ctx: &mut crate::Context, int: &I, - ) -> Result<(), FendError> { + ) -> FendCoreResult<()> { match self { Self::Num(n) => { n.clone() @@ -438,7 +436,7 @@ impl Value { Ok(()) } - pub(crate) fn get_object_member(self, key: &Ident) -> Result { + pub(crate) fn get_object_member(self, key: &Ident) -> FendCoreResult { match self { Self::Object(kv) => { for (k, v) in kv { diff --git a/core/src/value/built_in_function.rs b/core/src/value/built_in_function.rs index 8dc00c5d..e8fe762d 100644 --- a/core/src/value/built_in_function.rs +++ b/core/src/value/built_in_function.rs @@ -1,9 +1,9 @@ -use crate::deserialize_string; -use crate::serialize_string; +use crate::result::FendCoreResult; use crate::value::Expr; use crate::value::Ident; use crate::value::Scope; use crate::FendError; +use crate::{Deserialize, Serialize}; use std::{fmt, io}; use std::sync::Arc; @@ -54,7 +54,7 @@ impl BuiltInFunction { ) } - pub(crate) fn invert(self) -> Result { + pub(crate) fn invert(self) -> FendCoreResult { Ok(match self { Self::Sin => Value::BuiltInFunction(Self::Asin), Self::Cos => Value::BuiltInFunction(Self::Acos), @@ -101,7 +101,7 @@ impl BuiltInFunction { } } - fn try_from_str(s: &str) -> Result { + fn try_from_str(s: &str) -> FendCoreResult { Ok(match s { "approximately" => Self::Approximately, "abs" => Self::Abs, @@ -130,13 +130,12 @@ impl BuiltInFunction { }) } - pub(crate) fn serialize(self, write: &mut impl io::Write) -> Result<(), FendError> { - serialize_string(self.as_str(), write)?; - Ok(()) + pub(crate) fn serialize(self, write: &mut impl io::Write) -> FendCoreResult<()> { + self.as_str().serialize(write) } - pub(crate) fn deserialize(read: &mut impl io::Read) -> Result { - Self::try_from_str(deserialize_string(read)?.as_str()) + pub(crate) fn deserialize(read: &mut impl io::Read) -> FendCoreResult { + Self::try_from_str(String::deserialize(read)?.as_str()) } } diff --git a/core/tests/integration_tests.rs b/core/tests/integration_tests.rs index 2435de59..7654051f 100644 --- a/core/tests/integration_tests.rs +++ b/core/tests/integration_tests.rs @@ -5693,11 +5693,13 @@ fn permutation_test() { test_eval("10 permute 3", "720"); } +// ERROR #[test] fn date_literals() { test_eval_simple("@1970-01-01", "Thursday, 1 January 1970"); } +// ERROR #[test] fn date_literal_subtraction() { test_eval_simple("@2022-11-29 - 2 days", "Sunday, 27 November 2022");