1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
use Read;
use crate;
/// Reads an [expression](https://github.com/jiricekcz/fef-specification/blob/main/expressions/Expression.md) from a byte stream using a composer.
///
/// Reads an expression in the FEF (prefix) format from the byte stream and composes it into a custom type using the [composer](crate::v0::expr::traits::Composer).
/// Whenever an expression is read in the proces, the appropriate method of the composer is used to convert this expression into `S`. This value is then used
/// to read parent expressions. The most common type for `S` is probably `Box<Expr<S>>` (an in memory tree) - yielding a recursive type `Expr<Box<Expr<Box<Expr<...>>>>>`.
/// Since it is not possible to express this type directly in Rust, the [`ExprTree`] type is provided, which provides this functionality. If you want to read to
/// [`ExprTree`], use the [`read_expression_into_tree`] function.
///
/// # Type parameters
///
/// - `R`: The type of the byte stream reader.
/// - `C`: The type of the configuration.
/// - `S`: The type of the expression.
/// - `CP`: The type of the composer.
///
/// All but the `S` type parameter should in most cases be inferred.
///
/// # Usage
///
/// For usage, see the [`Composer`] trait.
Sized + Read, C: ?Sized + Config, S: Sized, CP: ?Sized + >
// TODO:
// PLEASE FIX THIS PIECE OF SHIT EXAMPLE AS SOON AS MORE ERGONOMIC EXPRESSION BUILDING PATTERNS ARE AVAILABLE.
// THIS IS VERY PAINFUL TO LOOK AT
/// Reads an [expression](https://github.com/jiricekcz/fef-specification/blob/main/expressions/Expression.md) from a byte stream and returns it as an [`ExprTree`].
///
/// This function is a convenience function that simplifies calling [`read_expression`] with a composer that composes to an [`ExprTree`].
/// For more information on parsing expressions, see the [`read_expression`] function.
///
/// # Example
/// Parsing the quadratic formula expression:
/// ```rust
/// # use fef::v0::read::read_expression_into_tree;
/// # use fef::v0::config::DEFAULT_CONFIG;
/// # use fef::v0::expr::ExprTree;
/// # use fef::v0::expr::Expr;
/// # use fef::v0::expr::ExprFalseLiteral;
/// # use fef::v0::expr::ExprVariable;
/// # use fef::v0::expr::ExprUnsignedIntLiteral;
/// # use fef::v0::expr::ExprAddition;
/// # use fef::v0::expr::ExprSubtraction;
/// # use fef::v0::expr::ExprMultiplication;
/// # use fef::v0::expr::ExprDivision;
/// # use fef::v0::expr::ExprSquareRoot;
/// # use fef::v0::expr::ExprSquare;
/// # use fef::v0::expr::ExprNegation;
/// # use fef::v0::raw::VariableLengthEnum;
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let bytes: Vec<u8> = vec![
/// 0x13, // Divide
/// 0x10, // Add - we will use the positive part
/// 0x17, // Negation
/// 0x04, 0x01, // Variable 1 (b)
/// 0x22, // Square root
/// 0x11, // Subtract
/// 0x20, // Square
/// 0x04, 0x01, // Variable 1 (b)
/// 0x12, // Multiply
/// 0x38, 0x04, // Number 4
/// 0x12, // Multiply
/// 0x04, 0x00, // Variable 0 (a)
/// 0x04, 0x02, // Variable 2 (c)
/// 0x12, // Multiply
/// 0x38, 0x02, // Number 2
/// 0x04, 0x00, // Variable 0 (a)
/// ];
///
/// let a: ExprTree = Expr::<ExprTree>::Variable(VariableLengthEnum::from(0).into()).into();
/// let b: ExprTree = Expr::<ExprTree>::Variable(VariableLengthEnum::from(1).into()).into();
/// let c: ExprTree = Expr::<ExprTree>::Variable(VariableLengthEnum::from(2).into()).into();
///
/// let four: ExprTree = Expr::<ExprTree>::UnsignedIntLiteral(
/// ExprUnsignedIntLiteral::from(4u64)
/// ).into();
/// let two: ExprTree = Expr::<ExprTree>::UnsignedIntLiteral(
/// ExprUnsignedIntLiteral::from(2u64)
/// ).into();
///
/// let ac: ExprTree = Expr::<ExprTree>::Multiplication(
/// ExprMultiplication::from((a.clone(), c.clone()))
/// ).into();
/// let four_ac: ExprTree = Expr::<ExprTree>::Multiplication(
/// ExprMultiplication::from((four.clone(), ac))
/// ).into();
///
/// let b_square: ExprTree = Expr::<ExprTree>::Square(
/// ExprSquare::from(b.clone())
/// ).into();
/// let b_square_minus_four_ac: ExprTree = Expr::<ExprTree>::Subtraction(
/// ExprSubtraction::from((b_square, four_ac))
/// ).into();
///
/// let sqrt_b_square_minus_four_ac: ExprTree = Expr::<ExprTree>::SquareRoot(
/// ExprSquareRoot::from(b_square_minus_four_ac)
/// ).into();
///
/// let minus_b: ExprTree = Expr::<ExprTree>::Negation(
/// ExprNegation::from(b.clone())
/// ).into();
///
/// let numerator: ExprTree = Expr::<ExprTree>::Addition(
/// ExprAddition::from((minus_b, sqrt_b_square_minus_four_ac))
/// ).into();
///
///
/// let denominator: ExprTree = Expr::<ExprTree>::Multiplication(
/// ExprMultiplication::from((two.clone(), a.clone()))
/// ).into();
///
///
/// let fraction: ExprTree = Expr::<ExprTree>::Division(
/// ExprDivision::from((numerator, denominator))
/// ).into();
///
///
/// let mut reader = &mut bytes.as_slice();
/// let expr = read_expression_into_tree(&mut reader, &DEFAULT_CONFIG)?;
///
/// assert_eq!(fraction, expr);
/// # Ok(())
/// # }
/// ```
Sized + Read, C: ?Sized + Config>