diff --git a/src/parsers/mod.rs b/src/parsers/mod.rs index 7284fc5..b59c3e1 100644 --- a/src/parsers/mod.rs +++ b/src/parsers/mod.rs @@ -71,13 +71,13 @@ impl BencodeParser { // Begin of list self.begin_bencoded_value()?; self.byte_writer.write_byte(b'[')?; - self.stack.push(State::ExpectingFirstItemOrEnd); + self.stack.push(State::ExpectingFirstListItemOrEnd); } b'd' => { // Begin of dictionary self.begin_bencoded_value()?; self.byte_writer.write_byte(b'{')?; - self.stack.push(State::ExpectingFirstFieldOrEnd); + self.stack.push(State::ExpectingFirstDictFieldOrEnd); } b'e' => { // End of list or dictionary (not end of integer) @@ -104,6 +104,13 @@ impl BencodeParser { Ok(()) } + /// JSON separator for items in a array + const JSON_ARRAY_ITEMS_SEPARATOR: u8 = b','; + /// JSON separator for field key and value in a object + const JSON_OBJ_FIELD_KEY_VALUE_SEPARATOR: u8 = b':'; + /// JSON separator for fields in a object + const JSON_OBJ_FIELDS_SEPARATOR: u8 = b','; + /// It updates the stack state and prints the delimiters when needed. /// /// Called when the first byt of a bencoded value (integer, string, list or dict) @@ -114,29 +121,26 @@ impl BencodeParser { /// Will return an error if the writer can't write to the output. pub fn begin_bencoded_value(&mut self) -> io::Result<()> { match self.stack.peek() { - // Initial state State::Initial => {} - // List - State::ExpectingFirstItemOrEnd => { - self.stack.swap_top(State::ExpectingNextItem); + State::ExpectingFirstListItemOrEnd => { + self.stack.swap_top(State::ExpectingNextListItem); } - State::ExpectingNextItem => { - // Items separator - self.byte_writer.write_byte(b',')?; + State::ExpectingNextListItem => { + self.byte_writer + .write_byte(Self::JSON_ARRAY_ITEMS_SEPARATOR)?; } - // Dictionary - State::ExpectingFirstFieldOrEnd => { - self.stack.swap_top(State::ExpectingFieldValue); + State::ExpectingFirstDictFieldOrEnd => { + self.stack.swap_top(State::ExpectingDictFieldValue); } - State::ExpectingFieldValue => { - // Key/Value separator - self.byte_writer.write_byte(b':')?; - self.stack.swap_top(State::ExpectingFieldKey); + State::ExpectingDictFieldValue => { + self.byte_writer + .write_byte(Self::JSON_OBJ_FIELD_KEY_VALUE_SEPARATOR)?; + self.stack.swap_top(State::ExpectingDictFieldKey); } - State::ExpectingFieldKey => { - // Field separator - self.byte_writer.write_byte(b',')?; - self.stack.swap_top(State::ExpectingFieldValue); + State::ExpectingDictFieldKey => { + self.byte_writer + .write_byte(Self::JSON_OBJ_FIELDS_SEPARATOR)?; + self.stack.swap_top(State::ExpectingDictFieldValue); } } @@ -158,14 +162,14 @@ impl BencodeParser { /// expected. pub fn end_bencoded_value(&mut self) -> io::Result<()> { match self.stack.peek() { - State::ExpectingFirstItemOrEnd | State::ExpectingNextItem => { + State::ExpectingFirstListItemOrEnd | State::ExpectingNextListItem => { self.byte_writer.write_byte(b']')?; self.stack.pop(); } - State::ExpectingFirstFieldOrEnd | State::ExpectingFieldKey => { + State::ExpectingFirstDictFieldOrEnd | State::ExpectingDictFieldKey => { self.byte_writer.write_byte(b'}')?; } - State::ExpectingFieldValue | State::Initial => { + State::ExpectingDictFieldValue | State::Initial => { // todo: pass the type of value (list or dict) to customize the error message panic!("error parsing end of list or dictionary, unexpected initial state on the stack") } diff --git a/src/parsers/stack.rs b/src/parsers/stack.rs index b6f2253..6560892 100644 --- a/src/parsers/stack.rs +++ b/src/parsers/stack.rs @@ -25,24 +25,24 @@ pub enum State { Initial, // I // States while parsing lists - ExpectingFirstItemOrEnd, // L - ExpectingNextItem, // M + ExpectingFirstListItemOrEnd, // L + ExpectingNextListItem, // M // States while parsing dictionaries - ExpectingFirstFieldOrEnd, // D - ExpectingFieldValue, // E - ExpectingFieldKey, // F + ExpectingFirstDictFieldOrEnd, // D + ExpectingDictFieldValue, // E + ExpectingDictFieldKey, // F } impl Display for State { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let output = match self { State::Initial => "I", - State::ExpectingFirstItemOrEnd => "L", - State::ExpectingNextItem => "M", - State::ExpectingFirstFieldOrEnd => "D", - State::ExpectingFieldValue => "E", - State::ExpectingFieldKey => "F", + State::ExpectingFirstListItemOrEnd => "L", + State::ExpectingNextListItem => "M", + State::ExpectingFirstDictFieldOrEnd => "D", + State::ExpectingDictFieldValue => "E", + State::ExpectingDictFieldKey => "F", }; write!(f, "{output}") }