Fix cargo doc links
This commit is contained in:
parent
ef97410fe5
commit
25d151465e
@ -9,13 +9,13 @@ use crate::TextOperator::{To, Of};
|
|||||||
use crate::FunctionIdentifier::*;
|
use crate::FunctionIdentifier::*;
|
||||||
use crate::lookup::{lookup_factorial, lookup_named_number};
|
use crate::lookup::{lookup_factorial, lookup_named_number};
|
||||||
|
|
||||||
/// Evaluate an [`AstNode`](struct.AstNode.html) into a [`Number`](struct.Number.html)
|
/// Evaluate an [`AstNode`] into a [`Number`]
|
||||||
pub fn evaluate(ast: &AstNode) -> Result<Number, String> {
|
pub fn evaluate(ast: &AstNode) -> Result<Number, String> {
|
||||||
let answer = evaluate_node(ast)?;
|
let answer = evaluate_node(ast)?;
|
||||||
Ok(answer)
|
Ok(answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the factorial of a [`d128`](../decimal/struct.d128.html) up to `1000!` without doing any math
|
/// Returns the factorial of a [`struct@d128`] up to `1000!` without doing any math
|
||||||
///
|
///
|
||||||
/// Factorials do not work with decimal numbers.
|
/// Factorials do not work with decimal numbers.
|
||||||
///
|
///
|
||||||
@ -24,7 +24,7 @@ pub fn factorial(input: d128) -> d128 {
|
|||||||
return lookup_factorial(input.into());
|
return lookup_factorial(input.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the square root of a [`d128`](../decimal/struct.d128.html)
|
/// Returns the square root of a [`struct@d128`]
|
||||||
pub fn sqrt(input: d128) -> d128 {
|
pub fn sqrt(input: d128) -> d128 {
|
||||||
let mut n = d128!(1);
|
let mut n = d128!(1);
|
||||||
let half = d128!(0.5);
|
let half = d128!(0.5);
|
||||||
@ -34,7 +34,7 @@ pub fn sqrt(input: d128) -> d128 {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the cube root of a [`d128`](../decimal/struct.d128.html)
|
/// Returns the cube root of a [`struct@d128`]
|
||||||
pub fn cbrt(input: d128) -> d128 {
|
pub fn cbrt(input: d128) -> d128 {
|
||||||
let mut n: d128 = input;
|
let mut n: d128 = input;
|
||||||
// hope that 20 iterations makes it accurate enough
|
// hope that 20 iterations makes it accurate enough
|
||||||
@ -46,7 +46,7 @@ pub fn cbrt(input: d128) -> d128 {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the sine of a [`d128`](../decimal/struct.d128.html)
|
/// Returns the sine of a [`struct@d128`]
|
||||||
pub fn sin(mut input: d128) -> d128 {
|
pub fn sin(mut input: d128) -> d128 {
|
||||||
let pi = d128!(3.141592653589793238462643383279503);
|
let pi = d128!(3.141592653589793238462643383279503);
|
||||||
let pi2 = d128!(6.283185307179586476925286766559006);
|
let pi2 = d128!(6.283185307179586476925286766559006);
|
||||||
@ -76,18 +76,18 @@ pub fn sin(mut input: d128) -> d128 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the cosine of a [`d128`](../decimal/struct.d128.html)
|
/// Returns the cosine of a [`struct@d128`]
|
||||||
pub fn cos(input: d128) -> d128 {
|
pub fn cos(input: d128) -> d128 {
|
||||||
let half_pi = d128!(1.570796326794896619231321691639751);
|
let half_pi = d128!(1.570796326794896619231321691639751);
|
||||||
return sin(half_pi - input);
|
return sin(half_pi - input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the tangent of a [`d128`](../decimal/struct.d128.html)
|
/// Returns the tangent of a [`struct@d128`]
|
||||||
pub fn tan(input: d128) -> d128 {
|
pub fn tan(input: d128) -> d128 {
|
||||||
return sin(input) / cos(input);
|
return sin(input) / cos(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate an [`AstNode`](struct.AstNode.html) into a [`Number`](struct.Number.html)
|
/// Evaluate an [`AstNode`] into a [`Number`]
|
||||||
fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
||||||
let token = &ast_node.token;
|
let token = &ast_node.token;
|
||||||
let children = &ast_node.children;
|
let children = &ast_node.children;
|
||||||
|
|||||||
@ -18,7 +18,7 @@ pub const fn is_alphabetic_extended(input: &char) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lex an input string and return a [`TokenVector`](../type.TokenVector.html)
|
/// Lex an input string and return a [`TokenVector`]
|
||||||
pub fn lex(input: &str, allow_trailing_operators: bool, default_degree: Unit) -> Result<TokenVector, String> {
|
pub fn lex(input: &str, allow_trailing_operators: bool, default_degree: Unit) -> Result<TokenVector, String> {
|
||||||
|
|
||||||
let mut input = input.replace(",", ""); // ignore commas
|
let mut input = input.replace(",", ""); // ignore commas
|
||||||
|
|||||||
40
src/lib.rs
40
src/lib.rs
@ -28,11 +28,11 @@ use crate::units::Unit;
|
|||||||
|
|
||||||
/// Units, and functions you can use with them
|
/// Units, and functions you can use with them
|
||||||
pub mod units;
|
pub mod units;
|
||||||
/// Turns a string into a [`TokenVector`](type.TokenVector.html)
|
/// Turns a string into a [`TokenVector`]
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
/// Turns a [`TokenVector`](type.TokenVector.html) into an [`AstNode`](struct.AstNode.html)
|
/// Turns a [`TokenVector`] into an [`AstNode`](parser::AstNode)
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
/// Turns an [`AstNode`](struct.AstNode.html) into a [`Number`](struct.Number.html)
|
/// Turns an [`AstNode`](parser::AstNode) into a [`Number`]
|
||||||
pub mod evaluator;
|
pub mod evaluator;
|
||||||
mod lookup;
|
mod lookup;
|
||||||
|
|
||||||
@ -51,9 +51,9 @@ mod lookup;
|
|||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Number {
|
pub struct Number {
|
||||||
/// The number part of a `Number` struct
|
/// The number part of a [`Number`] struct
|
||||||
pub value: d128,
|
pub value: d128,
|
||||||
/// The unit of a `Number` struct. This can be `NoType`
|
/// The unit of a [`Number`] struct. This can be [`NoType`](units::UnitType::NoType)
|
||||||
pub unit: Unit,
|
pub unit: Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ impl Number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Math operators like [`Multiply`](enum.Operator.html#variant.Multiply), parentheses, etc.
|
/// Math operators like [`Multiply`](Operator::Multiply), parentheses, etc.
|
||||||
pub enum Operator {
|
pub enum Operator {
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
@ -80,21 +80,21 @@ pub enum Operator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Unary operators like [`Percent`](enum.UnaryOperator.html#variant.Percent) and [`Factorial`](enum.UnaryOperator.html#variant.Factorial).
|
/// Unary operators like [`Percent`](UnaryOperator::Percent) and [`Factorial`](UnaryOperator::Factorial).
|
||||||
pub enum UnaryOperator {
|
pub enum UnaryOperator {
|
||||||
Percent,
|
Percent,
|
||||||
Factorial,
|
Factorial,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A Text operator like [`To`](enum.TextOperator.html#variant.To) or [`From`](enum.TextOperator.html#variant.From).
|
/// A Text operator like [`To`](TextOperator::To) or [`Of`](TextOperator::Of).
|
||||||
pub enum TextOperator {
|
pub enum TextOperator {
|
||||||
To,
|
To,
|
||||||
Of,
|
Of,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A named number like [`Million`](enum.NamedNumber.html#variant.Million).
|
/// A named number like [`Million`](NamedNumber::Million).
|
||||||
pub enum NamedNumber {
|
pub enum NamedNumber {
|
||||||
Hundred,
|
Hundred,
|
||||||
Thousand,
|
Thousand,
|
||||||
@ -123,14 +123,14 @@ pub enum NamedNumber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A constants like [`Pi`](enum.Constant.html#variant.Pi) or [`E`](enum.Constant.html#variant.E).
|
/// A constants like [`Pi`](Constant::Pi) or [`E`](Constant::E).
|
||||||
pub enum Constant {
|
pub enum Constant {
|
||||||
Pi,
|
Pi,
|
||||||
E,
|
E,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Functions identifiers like [`Sqrt`](enum.FunctionIdentifier.html#variant.Sqrt), [`Sin`](enum.FunctionIdentifier.html#variant.Sin), [`Round`](enum.FunctionIdentifier.html#variant.Round), etc.
|
/// Functions identifiers like [`Sqrt`](FunctionIdentifier::Sqrt), [`Sin`](FunctionIdentifier::Sin), [`Round`](FunctionIdentifier::Round), etc.
|
||||||
pub enum FunctionIdentifier {
|
pub enum FunctionIdentifier {
|
||||||
Sqrt,
|
Sqrt,
|
||||||
Cbrt,
|
Cbrt,
|
||||||
@ -150,13 +150,13 @@ pub enum FunctionIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A temporary enum used by the [`lexer`](lexer/index.html) to later determine what [`Token`](enum.Token.html) it is.
|
/// A temporary enum used by the [`lexer`] to later determine what [`Token`] it is.
|
||||||
///
|
///
|
||||||
/// For example, when a symbol like `%` is found, the lexer turns it into a
|
/// For example, when a symbol like `%` is found, the lexer turns it into a
|
||||||
/// the [`PercentChar`](enum.LexerKeyword.html#variant.PercentChar) variant
|
/// the [`PercentChar`](LexerKeyword::PercentChar) variant
|
||||||
/// and then later it checks the surrounding [`Token`](enum.Token.html)s and,
|
/// and then later it checks the surrounding [`Token`]s and,
|
||||||
/// dependingon them, turns it into a [`Percent`](enum.UnaryOperator.html) or
|
/// dependingon them, turns it into a [`Percent`](UnaryOperator::Percent) or
|
||||||
/// [`Modulo`](enum.Operator.html) [`Token`](enum.Token.html).
|
/// [`Modulo`](Operator::Modulo) [`Token`].
|
||||||
pub enum LexerKeyword {
|
pub enum LexerKeyword {
|
||||||
Per,
|
Per,
|
||||||
PercentChar,
|
PercentChar,
|
||||||
@ -170,9 +170,9 @@ pub enum LexerKeyword {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A token like a [`Number`](enum.Token.html#variant.Number), [`Operator`](enum.Token.html#variant.Operator), [`Unit`](enum.Token.html#variant.Unit) etc.
|
/// A token like a [`Number`](Token::Number), [`Operator`](Token::Operator), [`Unit`](Token::Unit) etc.
|
||||||
///
|
///
|
||||||
/// Strings can be divided up into these tokens by the [`lexer`](lexer/index.html), and then put into the [`parser`](parser/index.html).
|
/// Strings can be divided up into these tokens by the [`lexer`], and then put into the [`parser`].
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
UnaryOperator(UnaryOperator),
|
UnaryOperator(UnaryOperator),
|
||||||
@ -192,10 +192,10 @@ pub enum Token {
|
|||||||
Unit(units::Unit),
|
Unit(units::Unit),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A vector of [`Token`](enum.Token.html)
|
/// A vector of [`Token`]
|
||||||
pub type TokenVector = Vec<Token>;
|
pub type TokenVector = Vec<Token>;
|
||||||
|
|
||||||
/// Evaluates a string into a resulting [`Number`]().
|
/// Evaluates a string into a resulting [`Number`].
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::NamedNumber::*;
|
|||||||
use crate::NamedNumber;
|
use crate::NamedNumber;
|
||||||
use decimal_fixes_mirror::d128;
|
use decimal_fixes_mirror::d128;
|
||||||
|
|
||||||
/// Returns the number of a [`NamedNumber`](decimal/struct.d128.html) [`to`](../enum.NamedNumber.html) as a [`d128`](decimal/struct.d128.html)
|
/// Returns the corresponding [`d128`] of a [`NamedNumber`]
|
||||||
pub fn lookup_named_number(named_number: &NamedNumber) -> d128 {
|
pub fn lookup_named_number(named_number: &NamedNumber) -> d128 {
|
||||||
return match named_number {
|
return match named_number {
|
||||||
Hundred => d128!(100),
|
Hundred => d128!(100),
|
||||||
@ -32,7 +32,7 @@ pub fn lookup_named_number(named_number: &NamedNumber) -> d128 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the factorial of an `i32` as a [`d128`](decimal/struct.d128.html)
|
/// Returns the factorial of an `i32` as a [`struct@d128`]
|
||||||
pub fn lookup_factorial(n: i32) -> d128 {
|
pub fn lookup_factorial(n: i32) -> d128 {
|
||||||
return match n {
|
return match n {
|
||||||
0 => d128!(1),
|
0 => d128!(1),
|
||||||
|
|||||||
@ -5,11 +5,11 @@ use crate::TextOperator::{To, Of};
|
|||||||
use crate::units::Unit::{Foot, Inch};
|
use crate::units::Unit::{Foot, Inch};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// A struct with a [`Token`](struct.AstNode.html#structfield.token) and `AstNode` [`children`](struct.AstNode.html#structfield.children)
|
/// A struct with a [`Token`](AstNode::token) and [`AstNode`] [`children`](AstNode::children)
|
||||||
pub struct AstNode {
|
pub struct AstNode {
|
||||||
/// The children of the `AstNode`
|
/// The children of the [`AstNode`]
|
||||||
pub children: Vec<AstNode>,
|
pub children: Vec<AstNode>,
|
||||||
/// The token of the `AstNode`
|
/// The token of the [`AstNode`]
|
||||||
pub token: Token,
|
pub token: Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ impl AstNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse [`TokenVector`](type.TokenVector.html) into an Abstract Syntax Tree ([`AstNode`](struct.AstNode.html))
|
/// Parse [`TokenVector`] into an Abstract Syntax Tree ([`AstNode`])
|
||||||
pub fn parse(tokens: &TokenVector) -> Result<AstNode, String> {
|
pub fn parse(tokens: &TokenVector) -> Result<AstNode, String> {
|
||||||
parse_level_1(tokens, 0).and_then(|(ast, next_pos)| if next_pos == tokens.len() {
|
parse_level_1(tokens, 0).and_then(|(ast, next_pos)| if next_pos == tokens.len() {
|
||||||
Ok(ast)
|
Ok(ast)
|
||||||
@ -32,7 +32,7 @@ pub fn parse(tokens: &TokenVector) -> Result<AstNode, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 1 precedence (lowest): to, of
|
// level 1 precedence (lowest): to, of
|
||||||
/// Parse [`to`](../enum.TextOperator.html#variant.To) and [`of`](../enum.TextOperator.html#variant.Of)
|
/// Parse [`To`](crate::TextOperator::To) and [`Of`](crate::TextOperator::Of)
|
||||||
pub fn parse_level_1(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_1(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
// do higher precedences first, then come back down
|
// do higher precedences first, then come back down
|
||||||
let (mut node, mut pos) = parse_level_2(tokens, pos)?;
|
let (mut node, mut pos) = parse_level_2(tokens, pos)?;
|
||||||
@ -60,7 +60,7 @@ pub fn parse_level_1(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 2 precedence: +, -
|
// level 2 precedence: +, -
|
||||||
/// Parse [`Plus`](../enum.Operator.html#variant.Plus) and [`Minus`](../enum.Operator.html#variant.Minus)
|
/// Parse [`Plus`](crate::Operator::Plus) and [`Minus`](crate::Operator::Minus)
|
||||||
pub fn parse_level_2(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_2(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
let (mut node, mut pos) = parse_level_3(tokens, pos)?;
|
let (mut node, mut pos) = parse_level_3(tokens, pos)?;
|
||||||
loop {
|
loop {
|
||||||
@ -82,7 +82,7 @@ pub fn parse_level_2(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 3 precedence: *, /, modulo, implicative multiplication, foot-inch 6'4"
|
// level 3 precedence: *, /, modulo, implicative multiplication, foot-inch 6'4"
|
||||||
/// Parse [`Multiply`](../enum.Operator.html#variant.Multiply), [`Divide`](../enum.Operator.html#variant.Divide), [`Modulo`](../enum.Operator.html#variant.Modulo) and implicative multiplication (for example`2pi`)
|
/// Parse [`Multiply`](crate::Operator::Multiply), [`Divide`](crate::Operator::Divide), [`Modulo`](crate::Operator::Modulo) and implicative multiplication (for example`2pi`)
|
||||||
pub fn parse_level_3(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_3(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
|
|
||||||
// parse foot-inch syntax 6'4"
|
// parse foot-inch syntax 6'4"
|
||||||
@ -214,7 +214,7 @@ pub fn parse_level_3(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 4 precedence: ^
|
// level 4 precedence: ^
|
||||||
/// Parse [`Caret`](../enum.Operator.html#variant.Caret)
|
/// Parse [`Caret`](crate::Operator::Caret)
|
||||||
pub fn parse_level_4(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_4(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
let (mut node, mut pos) = parse_level_5(tokens, pos)?;
|
let (mut node, mut pos) = parse_level_5(tokens, pos)?;
|
||||||
loop {
|
loop {
|
||||||
@ -236,7 +236,7 @@ pub fn parse_level_4(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 5 precedence: - (as in -5, but not 4-5)
|
// level 5 precedence: - (as in -5, but not 4-5)
|
||||||
/// Parse [`Negative`](../enum.Token.html#variant.Negative)
|
/// Parse [`Negative`](Token::Negative)
|
||||||
pub fn parse_level_5(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_5(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
// Here we parse the negative unary operator. If the current token
|
// Here we parse the negative unary operator. If the current token
|
||||||
// is a minus, we wrap the right_node inside a Negative AstNode.
|
// is a minus, we wrap the right_node inside a Negative AstNode.
|
||||||
@ -263,7 +263,7 @@ pub fn parse_level_5(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 6 precedence: !, percent, units attached to values
|
// level 6 precedence: !, percent, units attached to values
|
||||||
/// Parse [`Factorial`](../enum.UnaryOperator.html#variant.Factorial) and [`Percent`](../enum.UnaryOperator.html#variant.Percent)
|
/// Parse [`Factorial`](crate::UnaryOperator::Factorial) and [`Percent`](crate::UnaryOperator::Percent)
|
||||||
pub fn parse_level_6(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_6(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
let (mut node, mut pos) = parse_level_7(tokens, pos)?;
|
let (mut node, mut pos) = parse_level_7(tokens, pos)?;
|
||||||
loop {
|
loop {
|
||||||
@ -295,11 +295,11 @@ pub fn parse_level_6(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize
|
|||||||
}
|
}
|
||||||
|
|
||||||
// level 7 precedence: numbers, standalone units, constants, functions, parens
|
// level 7 precedence: numbers, standalone units, constants, functions, parens
|
||||||
/// Parse [`Number`](../enum.Token.html#variant.Number),
|
/// Parse [`Number`](Token::Number),
|
||||||
/// [`Unit`](../units/enum.Unit.html),
|
/// [`Unit`](Token::Unit),
|
||||||
/// [`Constant`](../enum.Constant.html),
|
/// [`Constant`](Token::Constant),
|
||||||
/// [`FunctionIdentifier`](../enum.FunctionIdentifier.html),
|
/// [`FunctionIdentifier`](Token::FunctionIdentifier),
|
||||||
/// [`Paren`](../enum.Token.html#variant.Paren)
|
/// [`Paren`](Token::Paren)
|
||||||
pub fn parse_level_7(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
pub fn parse_level_7(tokens: &TokenVector, pos: usize) -> Result<(AstNode, usize), String> {
|
||||||
let token: &Token = tokens.get(pos).ok_or(format!("Unexpected end of input at {}", pos))?;
|
let token: &Token = tokens.get(pos).ok_or(format!("Unexpected end of input at {}", pos))?;
|
||||||
match token {
|
match token {
|
||||||
|
|||||||
94
src/units.rs
94
src/units.rs
@ -2,40 +2,40 @@ use decimal_fixes_mirror::d128;
|
|||||||
use crate::Number;
|
use crate::Number;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
/// An enum of all possible unit types, like `Length`, `DigitalStorage` etc.
|
/// An enum of all possible unit types, like [`Length`], [`DigitalStorage`] etc.
|
||||||
/// There is also a `NoType` unit type for normal numbers.
|
/// There is also a [`NoType`] unit type for normal numbers.
|
||||||
pub enum UnitType {
|
pub enum UnitType {
|
||||||
/// A normal number, for example `5`
|
/// A normal number, for example `5`
|
||||||
NoType,
|
NoType,
|
||||||
/// A unit of time, for example `Hour`
|
/// A unit of time, for example [`Hour`]
|
||||||
Time,
|
Time,
|
||||||
/// A unit of length, for example `Mile`
|
/// A unit of length, for example [`Mile`]
|
||||||
Length,
|
Length,
|
||||||
/// A unit of area, for example `SquareKilometer`
|
/// A unit of area, for example [`SquareKilometer`]
|
||||||
Area,
|
Area,
|
||||||
/// A unit of volume, for example `Liter` or `Tablespoon`
|
/// A unit of volume, for example [`Liter`] or [`Tablespoon`]
|
||||||
Volume,
|
Volume,
|
||||||
/// A unit of mass, for example `Kilobyte`
|
/// A unit of mass, for example [`Gram`]
|
||||||
Mass,
|
Mass,
|
||||||
/// A unit of digital storage, for example `Kilobyte`
|
/// A unit of digital storage, for example [`Kilobyte`]
|
||||||
DigitalStorage,
|
DigitalStorage,
|
||||||
/// A unit of energy, for example `Joule` or `KilowattHour`
|
/// A unit of energy, for example [`Joule`] or [`KilowattHour`]
|
||||||
Energy,
|
Energy,
|
||||||
/// A unit of power, for example `Watt`
|
/// A unit of power, for example [`Watt`]
|
||||||
Power,
|
Power,
|
||||||
/// A unit of electrical current, for example `Ampere`
|
/// A unit of electrical current, for example [`Ampere`]
|
||||||
ElectricCurrent,
|
ElectricCurrent,
|
||||||
/// A unit of electric resistance, for example `Ohm`
|
/// A unit of electric resistance, for example [`Ohm`]
|
||||||
Resistance,
|
Resistance,
|
||||||
/// A unit of voltage, for example `Volt`
|
/// A unit of voltage, for example [`Volt`]
|
||||||
Voltage,
|
Voltage,
|
||||||
/// A unit of pressure, for example `Bar`
|
/// A unit of pressure, for example [`Bar`]
|
||||||
Pressure,
|
Pressure,
|
||||||
/// A unit of frequency, for example `Hertz`
|
/// A unit of frequency, for example [`Hertz`]
|
||||||
Frequency,
|
Frequency,
|
||||||
/// A unit of x, for example `KilometersPerHour`
|
/// A unit of x, for example [`KilometersPerHour`]
|
||||||
Speed,
|
Speed,
|
||||||
/// A unit of temperature, for example `Kelvin`
|
/// A unit of temperature, for example [`Kelvin`]
|
||||||
Temperature,
|
Temperature,
|
||||||
}
|
}
|
||||||
use UnitType::*;
|
use UnitType::*;
|
||||||
@ -46,7 +46,7 @@ use UnitType::*;
|
|||||||
macro_rules! create_units {
|
macro_rules! create_units {
|
||||||
( $( $variant:ident : $properties:expr ),*, ) => {
|
( $( $variant:ident : $properties:expr ),*, ) => {
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
/// A Unit enum. Note that it can also be `NoUnit`.
|
/// A Unit enum. Note that it can also be [`NoUnit`].
|
||||||
pub enum Unit {
|
pub enum Unit {
|
||||||
$($variant),*
|
$($variant),*
|
||||||
}
|
}
|
||||||
@ -285,12 +285,12 @@ fn get_inverted_millivolt_weight() -> d128 {
|
|||||||
/// `to_unit`. For example, the conversion factor from 1 minute to 1 second
|
/// `to_unit`. For example, the conversion factor from 1 minute to 1 second
|
||||||
/// is 60.
|
/// is 60.
|
||||||
///
|
///
|
||||||
/// This is not sufficient for `Temperature` units.
|
/// This is not sufficient for [`Temperature`] units.
|
||||||
pub fn get_conversion_factor(unit: Unit, to_unit: Unit) -> d128 {
|
pub fn get_conversion_factor(unit: Unit, to_unit: Unit) -> d128 {
|
||||||
return unit.weight() / to_unit.weight();
|
return unit.weight() / to_unit.weight();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a [`Number`](struct.Number.html) to a specified [`Unit`](enum.Unit.html).
|
/// Convert a [`Number`] to a specified [`Unit`].
|
||||||
pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
||||||
if number.unit.category() != to_unit.category() {
|
if number.unit.category() != to_unit.category() {
|
||||||
return Err(format!("Cannot convert from {:?} to {:?}", number.unit, to_unit));
|
return Err(format!("Cannot convert from {:?} to {:?}", number.unit, to_unit));
|
||||||
@ -318,7 +318,7 @@ pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If one of two provided [`Number`](struct.Number.html)s has a larger [`Unit`](enum.Unit.html) than the other, convert
|
/// If one of two provided [`Number`]s has a larger [`Unit`] than the other, convert
|
||||||
/// the large one to the unit of the small one.
|
/// the large one to the unit of the small one.
|
||||||
pub fn convert_to_lowest(left: Number, right: Number) -> Result<(Number, Number), String> {
|
pub fn convert_to_lowest(left: Number, right: Number) -> Result<(Number, Number), String> {
|
||||||
if left.unit.weight() == right.unit.weight() {
|
if left.unit.weight() == right.unit.weight() {
|
||||||
@ -332,7 +332,7 @@ pub fn convert_to_lowest(left: Number, right: Number) -> Result<(Number, Number)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the sum of two [`Number`](enum.Number.html)s
|
/// Return the sum of two [`Number`]s
|
||||||
pub fn add(left: Number, right: Number) -> Result<Number, String> {
|
pub fn add(left: Number, right: Number) -> Result<Number, String> {
|
||||||
if left.unit == right.unit {
|
if left.unit == right.unit {
|
||||||
Ok(Number::new(left.value + right.value, left.unit))
|
Ok(Number::new(left.value + right.value, left.unit))
|
||||||
@ -344,7 +344,7 @@ pub fn add(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract a [`Number`](enum.Number.html) from another [`Number`](enum.Number.html)
|
/// Subtract a [`Number`] from another [`Number`]
|
||||||
pub fn subtract(left: Number, right: Number) -> Result<Number, String> {
|
pub fn subtract(left: Number, right: Number) -> Result<Number, String> {
|
||||||
if left.unit == right.unit {
|
if left.unit == right.unit {
|
||||||
Ok(Number::new(left.value - right.value, left.unit))
|
Ok(Number::new(left.value - right.value, left.unit))
|
||||||
@ -356,7 +356,7 @@ pub fn subtract(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert [`Number`](enum.Number.html) to an ideal unit.
|
/// Convert a [`Number`] to an ideal unit.
|
||||||
///
|
///
|
||||||
/// If you have 1,000,000 millimeters, this will return 1 kilometer.
|
/// If you have 1,000,000 millimeters, this will return 1 kilometer.
|
||||||
///
|
///
|
||||||
@ -462,7 +462,7 @@ pub fn to_ideal_unit(number: Number) -> Number {
|
|||||||
number
|
number
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a [`Number`](enum.Number.html) to an ideal joule unit, if the number is .
|
/// Convert a [`Number`] to an ideal [`Joule`] unit, if the number is a unit of [`Energy`].
|
||||||
pub fn to_ideal_joule_unit(number: Number) -> Number {
|
pub fn to_ideal_joule_unit(number: Number) -> Number {
|
||||||
let value = number.value * number.unit.weight();
|
let value = number.value * number.unit.weight();
|
||||||
if number.unit.category() == Energy {
|
if number.unit.category() == Energy {
|
||||||
@ -483,15 +483,15 @@ pub fn to_ideal_joule_unit(number: Number) -> Number {
|
|||||||
number
|
number
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiply two [`Number`](enum.Number.html)s
|
/// Multiply two [`Number`]s
|
||||||
///
|
///
|
||||||
/// - Temperatures don't work
|
/// - Temperatures don't work
|
||||||
/// - If you multiply `NoType` with any other unit, the result gets that other unit
|
/// - If you multiply [`NoType`] with any other unit, the result gets that other unit
|
||||||
/// - If you multiply `Length` with `Length`, the result has a unit of `Area`, etc.
|
/// - If you multiply [`Length`] with [`Length`], the result has a unit of [`Area`], etc.
|
||||||
/// - If you multiply `Speed` with `Time`, the result has a unit of `Length`
|
/// - If you multiply [`Speed`] with [`Time`], the result has a unit of [`Length`]
|
||||||
/// - If you multiply `Voltage` with `Current`, the result has a unit of `Power`
|
/// - If you multiply [`Voltage`] with [`ElectricCurrent`], the result has a unit of [`Power`]
|
||||||
/// - If you multiply `Current` with `Resistance`, the result has a unit of `Voltage`
|
/// - If you multiply [`ElectricCurrent`] with [`Resistance`], the result has a unit of [`Voltage`]
|
||||||
/// - If you multiply `Power` with `Time`, the result has a unit of `Energy`
|
/// - If you multiply [`Power`] with [`Time`], the result has a unit of [`Energy`]
|
||||||
pub fn multiply(left: Number, right: Number) -> Result<Number, String> {
|
pub fn multiply(left: Number, right: Number) -> Result<Number, String> {
|
||||||
Ok(actual_multiply(left, right, false)?)
|
Ok(actual_multiply(left, right, false)?)
|
||||||
}
|
}
|
||||||
@ -555,17 +555,17 @@ fn actual_multiply(left: Number, right: Number, swapped: bool) -> Result<Number,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divide a [`Number`](enum.Number.html) by another [`Number`](enum.Number.html)
|
/// Divide a [`Number`] by another [`Number`]
|
||||||
///
|
///
|
||||||
/// - Temperatures don't work
|
/// - Temperatures don't work
|
||||||
/// - If you divide a unit by that same unit, the result has a unit of `NoType`
|
/// - If you divide a unit by that same unit, the result has a unit of [`NoType`]
|
||||||
/// - If you divide `Volume` by `Length`, the result has a unit of `Area`, etc.
|
/// - If you divide [`Volume`] by [`Length`], the result has a unit of [`Area`], etc.
|
||||||
/// - If you divide `Length` by `Time`, the result has a unit of `Speed`
|
/// - If you divide [`Length`] by [`Time`], the result has a unit of [`Speed`]
|
||||||
/// - If you divide `Power` by `ElectricCurrent`, the result has a unit of `Volt`
|
/// - If you divide [`Power`] by [`ElectricCurrent`], the result has a unit of [`Volt`]
|
||||||
/// - If you divide `Voltage` by `ElectricCurrent`, the result has a unit of `Ohm`
|
/// - If you divide [`Voltage`] by [`ElectricCurrent`], the result has a unit of [`Ohm`]
|
||||||
/// - If you divide `Voltage` by `Resistance`, the result has a unit of `Ampere`
|
/// - If you divide [`Voltage`] by [`Resistance`], the result has a unit of [`Ampere`]
|
||||||
/// - If you divide `Power` by `Voltage`, the result has a unit of `Ampere`
|
/// - If you divide [`Power`] by [`Voltage`], the result has a unit of [`Ampere`]
|
||||||
/// - If you divide `Energy` by `Time`, the result has a unit of `Power`
|
/// - If you divide [`Energy`] by [`Time`], the result has a unit of [`Power`]
|
||||||
pub fn divide(left: Number, right: Number) -> Result<Number, String> {
|
pub fn divide(left: Number, right: Number) -> Result<Number, String> {
|
||||||
let lcat = left.unit.category();
|
let lcat = left.unit.category();
|
||||||
let rcat = right.unit.category();
|
let rcat = right.unit.category();
|
||||||
@ -628,9 +628,9 @@ pub fn divide(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
Err(format!("Cannot divide {:?} by {:?}", left.unit, right.unit))
|
Err(format!("Cannot divide {:?} by {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Modulo a [`Number`](enum.Number.html) by another [`Number`](enum.Number.html).
|
/// Modulo a [`Number`] by another [`Number`].
|
||||||
///
|
///
|
||||||
/// `left` and `right` need to have the same `UnitType`, and the result will have that same `UnitType`.
|
/// `left` and `right` need to have the same [`UnitType`], and the result will have that same [`UnitType`].
|
||||||
///
|
///
|
||||||
/// Temperatures don't work.
|
/// Temperatures don't work.
|
||||||
pub fn modulo(left: Number, right: Number) -> Result<Number, String> {
|
pub fn modulo(left: Number, right: Number) -> Result<Number, String> {
|
||||||
@ -646,11 +646,11 @@ pub fn modulo(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [`Number`](enum.Number.html) to the power of another [`Number`](enum.Number.html)
|
/// Returns a [`Number`] to the power of another [`Number`]
|
||||||
///
|
///
|
||||||
/// - If you take `Length` to the power of `NoType`, the result has a unit of `Area`.
|
/// - If you take [`Length`] to the power of [`NoType`], the result has a unit of [`Area`].
|
||||||
/// - If you take `Length` to the power of `Length`, the result has a unit of `Area`
|
/// - If you take [`Length`] to the power of [`Length`], the result has a unit of [`Area`]
|
||||||
/// - If you take `Length` to the power of `Area`, the result has a unit of `Volume`
|
/// - If you take [`Length`] to the power of [`Area`], the result has a unit of [`Volume`]
|
||||||
/// - etc.
|
/// - etc.
|
||||||
pub fn pow(left: Number, right: Number) -> Result<Number, String> {
|
pub fn pow(left: Number, right: Number) -> Result<Number, String> {
|
||||||
let lcat = left.unit.category();
|
let lcat = left.unit.category();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user