51 lines
1.4 KiB
Markdown
51 lines
1.4 KiB
Markdown
---
|
|
name = "Parse"
|
|
file = "src/string/parse.rs"
|
|
---
|
|
|
|
Parsing is the act of extracting structured information from a string of symbols. In programming we generaly parse raw bytes, or even sometimes strings of bits. In Rust, we have very rudimentary parsing utility, allowing user to parse most simple standard types from `&str`. This is encoded in the [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait.
|
|
|
|
Let's parse simple structured data. Remember the type we introduced in the Forth exercise ?
|
|
|
|
```rust
|
|
pub enum Operation {
|
|
Push(f32),
|
|
Binary(Binary),
|
|
}
|
|
|
|
pub enum Binary {
|
|
Add,
|
|
Sub,
|
|
Mul,
|
|
Div,
|
|
}
|
|
```
|
|
|
|
Let's implement `FromStr` for the `Binary` and `Operation` types. Any number should create a `Push`, and we will map `"+"` to `Add`, `"-"` to `Sub`, `"*"` to `Mul`, and `"/"` to `Div`.
|
|
|
|
```prototype
|
|
use crate::vec::forth;
|
|
use std::str::FromStr;
|
|
|
|
#[derive(PartialEq, Debug)]
|
|
pub enum ParseOperationError {
|
|
Number(std::num::ParseFloatError),
|
|
UnknownOperation,
|
|
}
|
|
|
|
impl FromStr for Operation {
|
|
type Err = ParseOperationError;
|
|
|
|
fn from_str(s: &str) -> Result<Operation, ParseOperationError> {
|
|
unimplemented!()
|
|
}
|
|
}
|
|
```
|
|
|
|
```example
|
|
fn main() {
|
|
assert_eq!("123".parse(), Ok(Operation::Push(123)));
|
|
assert_eq!("+".parse(), Ok(Operation::Binary(Binary::Add)));
|
|
assert_eq!("foo".parse(), Err(ParseOperationError::UnknownOperation));
|
|
}
|