Skip to content

Commit

Permalink
refactor: extract integer parser
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Sep 24, 2024
1 parent ff8d2bc commit e0e5599
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 33 deletions.
36 changes: 3 additions & 33 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ use std::str::{self};

use byte_reader::ByteReader;
use byte_writer::ByteWriter;
use parsers::integer;
use stack::{Stack, State};

pub mod byte_reader;
pub mod byte_writer;
pub mod parsers;
pub mod stack;

pub struct BencodeParser<R: Read, W: Write> {
Expand Down Expand Up @@ -257,39 +259,7 @@ impl<R: Read, W: Write> BencodeParser<R, W> {
}

fn parse_integer(&mut self) -> io::Result<()> {
/*
st = 0 -> Parsed begin integer (`i`)
st = 1 -> Parsed sign (only negative is allowed)
st = 2 -> Parsing digits
st = 3 -> Parsed end integer (`e`)
*/

let mut st = 0;

loop {
let byte = match self.byte_reader.read_byte() {
Ok(byte) => byte,
Err(ref err) if err.kind() == io::ErrorKind::UnexpectedEof => {
//println!("Reached the end of file.");
panic!("unexpected end of input parsing integer");
}
Err(err) => return Err(err),
};

let char = byte as char;

if char.is_ascii_digit() {
st = 2;
self.byte_writer.write_byte(byte)?;
} else if char == 'e' && st == 2 {
return Ok(());
} else if char == '-' && st == 0 {
st = 1;
self.byte_writer.write_byte(byte)?;
} else {
panic!("invalid integer");
}
}
integer::parse(&mut self.byte_reader, &mut self.byte_writer)
}

fn parse_string(&mut self, byte: u8) -> io::Result<()> {
Expand Down
52 changes: 52 additions & 0 deletions src/parsers/integer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::io::{self, Read, Write};

use crate::{byte_reader::ByteReader, byte_writer::ByteWriter};

/// It parses an integer bencoded value.
///
/// # Errors
///
/// Will return an error if it can't read from the input or write to the
/// output.
///
/// # Panics
///
/// Will panic if we reach the end of the input without completing the
/// integer (without reaching the end of the integer `e`).
pub fn parse<R: Read, W: Write>(
reader: &mut ByteReader<R>,
writer: &mut ByteWriter<W>,
) -> io::Result<()> {
/*
st = 0 -> Parsed begin integer (`i`)
st = 1 -> Parsed sign (only negative is allowed)
st = 2 -> Parsing digits
st = 3 -> Parsed end integer (`e`)
*/

let mut st = 0;

loop {
let byte = match reader.read_byte() {
Ok(byte) => byte,
Err(ref err) if err.kind() == io::ErrorKind::UnexpectedEof => {
panic!("unexpected end of input parsing integer");
}
Err(err) => return Err(err),
};

let char = byte as char;

if char.is_ascii_digit() {
st = 2;
writer.write_byte(byte)?;
} else if char == 'e' && st == 2 {
return Ok(());
} else if char == '-' && st == 0 {
st = 1;
writer.write_byte(byte)?;
} else {
panic!("invalid integer");
}
}
}
1 change: 1 addition & 0 deletions src/parsers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod integer;

0 comments on commit e0e5599

Please sign in to comment.