diff --git a/src/bencode.rs b/src/bencode.rs index 24d82fd..ca64d01 100644 --- a/src/bencode.rs +++ b/src/bencode.rs @@ -73,14 +73,14 @@ impl Display for Bencode { impl Bencode { - pub fn encode(&self) -> Vec { + pub fn compose(&self) -> Vec { match self { Bencode::Integer(i) => {format!("i{}e", i).as_bytes().to_vec()} Bencode::Bytes(b) => {[format!("{}:", b.0.len()).as_bytes(), &b.0[..]].concat()} Bencode::List(l) => { let mut result = vec!['l' as u8]; for item in l { - result.extend(item.encode()) + result.extend(item.compose()) } result.push('e' as u8); result @@ -88,16 +88,16 @@ impl Bencode { Bencode::Dict(d) => { let mut result = vec!['d' as u8]; for (k, v) in d { - result.extend(Self::encode(&Bencode::Bytes(k.clone()))); - result.extend(v.encode()); + result.extend(Self::compose(&Bencode::Bytes(k.clone()))); + result.extend(v.compose()); } result.push('e' as u8); result } } } - pub fn decode(input: &[u8]) -> Result { - let (result, end_pos) = Self::decode_type(input)?; + pub fn parse(input: &[u8]) -> Result { + let (result, end_pos) = Self::parse_type(input)?; ensure!(end_pos == input.len() - 1, "Could not fully decode input. Got {} chars left to decode", input.len() - 1 - end_pos); Ok(result) @@ -106,12 +106,12 @@ impl Bencode { pub fn sha1(&self) -> [u8; 20] { let mut hasher = Sha1::new(); - hasher.update(self.encode()); + hasher.update(self.compose()); hasher.finalize().into() } - fn decode_type(input: &[u8]) -> Result<(Bencode, usize)>{ + fn parse_type(input: &[u8]) -> Result<(Bencode, usize)>{ if input.len() == 0 { return Err(anyhow!("Empty string is not valid bencode")) } @@ -140,7 +140,7 @@ impl Bencode { let (to_decode, end_decoded) = match type_ { BencodeType::Integer => (&input[1..end_to_decode], end_to_decode), BencodeType::Bytes => { - let bytes_len = Self::decode_int_only(&input[0..end_to_decode])? as usize; + let bytes_len = Self::parse_int_only(&input[0..end_to_decode])? as usize; let bytes_start= end_to_decode + 1; let end_pos = bytes_start + bytes_len; (&input[bytes_start..end_pos], end_pos - 1) @@ -150,39 +150,39 @@ impl Bencode { match type_ { BencodeType::Integer => { - let result = Self::decode_int(to_decode)?; + let result = Self::parse_int(to_decode)?; Ok((result, end_decoded)) }, BencodeType::Bytes => { - let result = Self::decode_bytes(to_decode)?; + let result = Self::parse_bytes(to_decode)?; Ok((result, end_decoded)) }, BencodeType::List => { - let (result, end_pos) = Self::decode_list(to_decode)?; + let (result, end_pos) = Self::parse_list(to_decode)?; Ok((result, end_pos + 1)) }, BencodeType::Dict => { - let (result, end_pos) = Self::decode_dict(to_decode)?; + let (result, end_pos) = Self::parse_dict(to_decode)?; Ok((result, end_pos + 1)) }, } } - fn decode_int_only(input: &[u8]) -> Result { + fn parse_int_only(input: &[u8]) -> Result { let int_str = std::str::from_utf8(input)?; int_str.parse::().map_err(anyhow::Error::msg) } - fn decode_int(input: &[u8]) -> Result { - let int = Self::decode_int_only(input)?; + fn parse_int(input: &[u8]) -> Result { + let int = Self::parse_int_only(input)?; Ok(Bencode::Integer(int)) } - fn decode_bytes(input: &[u8]) -> Result { + fn parse_bytes(input: &[u8]) -> Result { Ok(Bencode::Bytes(ByteString::from_slice(input))) } - fn decode_list(input: &[u8]) -> Result<(Bencode, usize)> { + fn parse_list(input: &[u8]) -> Result<(Bencode, usize)> { let mut result = Vec::new(); let mut decoded_pos = 0; loop { @@ -192,14 +192,14 @@ impl Bencode { if input[decoded_pos] == 'e' as u8 { break; } - let (li_result, end_pos ) = Self::decode_type(&input[decoded_pos..])?; + let (li_result, end_pos ) = Self::parse_type(&input[decoded_pos..])?; result.push(li_result); decoded_pos += end_pos + 1; } Ok((Bencode::List(result), decoded_pos)) } - fn decode_dict(input: &[u8]) -> Result<(Bencode, usize)> { + fn parse_dict(input: &[u8]) -> Result<(Bencode, usize)> { let mut result = HashMap::new(); let mut decoded_pos = 0; loop { @@ -209,11 +209,11 @@ impl Bencode { if input[decoded_pos] == 'e' as u8 { break; } - let (Bencode::Bytes(key_result), end_pos) = Self::decode_type(&input[decoded_pos..])? else { + let (Bencode::Bytes(key_result), end_pos) = Self::parse_type(&input[decoded_pos..])? else { return Err(anyhow!("Type of dictionary key not Bytes")) }; decoded_pos += end_pos + 1; - let (value_result, end_pos) = Self::decode_type(&input[decoded_pos..])?; + let (value_result, end_pos) = Self::parse_type(&input[decoded_pos..])?; result.insert(key_result, value_result); decoded_pos += end_pos + 1; } @@ -233,75 +233,75 @@ mod tests { } #[test] - fn test_encode_int() { - assert_eq!(Bencode::Integer(42).encode(), "i42e".as_bytes()); - assert_eq!(Bencode::Integer(17).encode(), "i17e".as_bytes()); + fn test_compose_int() { + assert_eq!(Bencode::Integer(42).compose(), "i42e".as_bytes()); + assert_eq!(Bencode::Integer(17).compose(), "i17e".as_bytes()); } #[test] - fn test_encode_bytes() { - assert_eq!(Bencode::Bytes(ByteString::from_str("foo")).encode(), "3:foo".as_bytes()); - assert_eq!(Bencode::Bytes(ByteString::from_str("bar")).encode(), "3:bar".as_bytes()); + fn test_compose_bytes() { + assert_eq!(Bencode::Bytes(ByteString::from_str("foo")).compose(), "3:foo".as_bytes()); + assert_eq!(Bencode::Bytes(ByteString::from_str("bar")).compose(), "3:bar".as_bytes()); } #[test] - fn test_encode_list() { - assert_eq!(Bencode::List(vec![Bencode::Bytes(ByteString::from_str("foo")), Bencode::Integer(42)]).encode(), "l3:fooi42ee".as_bytes()); + fn test_compose_list() { + assert_eq!(Bencode::List(vec![Bencode::Bytes(ByteString::from_str("foo")), Bencode::Integer(42)]).compose(), "l3:fooi42ee".as_bytes()); } #[test] - fn test_encode_dict() { - assert_eq!(Bencode::Dict(HashMap::from([(ByteString::from_str("foo"), Bencode::Integer(42))])).encode(), "d3:fooi42ee".as_bytes()); + fn test_compose_dict() { + assert_eq!(Bencode::Dict(HashMap::from([(ByteString::from_str("foo"), Bencode::Integer(42))])).compose(), "d3:fooi42ee".as_bytes()); } #[test] fn test_integer_only() { - assert_eq!(Bencode::decode_int_only("42".as_bytes()).unwrap(), 42); - assert_eq!(Bencode::decode_int_only("17".as_bytes()).unwrap(), 17); - assert_eq!(Bencode::decode_int_only("-17".as_bytes()).unwrap(), -17); + assert_eq!(Bencode::parse_int_only("42".as_bytes()).unwrap(), 42); + assert_eq!(Bencode::parse_int_only("17".as_bytes()).unwrap(), 17); + assert_eq!(Bencode::parse_int_only("-17".as_bytes()).unwrap(), -17); } #[test] fn test_integer() { - assert_eq!(Bencode::decode_int("42".as_bytes()).unwrap(), Bencode::Integer(42)); - assert_eq!(Bencode::decode_int("17".as_bytes()).unwrap(), Bencode::Integer(17)); - assert_eq!(Bencode::decode_int("-17".as_bytes()).unwrap(), Bencode::Integer(-17)); + assert_eq!(Bencode::parse_int("42".as_bytes()).unwrap(), Bencode::Integer(42)); + assert_eq!(Bencode::parse_int("17".as_bytes()).unwrap(), Bencode::Integer(17)); + assert_eq!(Bencode::parse_int("-17".as_bytes()).unwrap(), Bencode::Integer(-17)); } #[test] fn test_integer_str() { - assert_eq!(Bencode::decode("i42e".as_bytes()).unwrap(), Bencode::Integer(42)); - assert_eq!(Bencode::decode("i17e".as_bytes()).unwrap(), Bencode::Integer(17)); - assert_eq!(Bencode::decode("i-17e".as_bytes()).unwrap(), Bencode::Integer(-17)); + assert_eq!(Bencode::parse("i42e".as_bytes()).unwrap(), Bencode::Integer(42)); + assert_eq!(Bencode::parse("i17e".as_bytes()).unwrap(), Bencode::Integer(17)); + assert_eq!(Bencode::parse("i-17e".as_bytes()).unwrap(), Bencode::Integer(-17)); } #[test] fn test_bytes() { - assert_eq!(Bencode::decode_bytes("hallo".as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("hallo"))); - assert_eq!(Bencode::decode_bytes("tschüss".as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("tschüss"))); - assert_eq!(Bencode::decode_bytes("💩".as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("💩"))); + assert_eq!(Bencode::parse_bytes("hallo".as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("hallo"))); + assert_eq!(Bencode::parse_bytes("tschüss".as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("tschüss"))); + assert_eq!(Bencode::parse_bytes("💩".as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("💩"))); } - fn util_encode_bytes(input: &str) -> String { + fn util_compose_bytes(input: &str) -> String { format!("{}:{input}", input.len()) } #[test] fn test_bytes_str() { - assert_eq!(Bencode::decode(util_encode_bytes("hallo").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("hallo"))); - assert_eq!(Bencode::decode(util_encode_bytes("tschüss").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("tschüss"))); - assert_eq!(Bencode::decode(util_encode_bytes("💩").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("💩"))); - assert_eq!(Bencode::decode(util_encode_bytes("hallo 💩, this is a long text").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("hallo 💩, this is a long text"))); + assert_eq!(Bencode::parse(util_compose_bytes("hallo").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("hallo"))); + assert_eq!(Bencode::parse(util_compose_bytes("tschüss").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("tschüss"))); + assert_eq!(Bencode::parse(util_compose_bytes("💩").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("💩"))); + assert_eq!(Bencode::parse(util_compose_bytes("hallo 💩, this is a long text").as_bytes()).unwrap(), Bencode::Bytes(ByteString::from_str("hallo 💩, this is a long text"))); } #[test] fn test_list() { - assert_eq!(Bencode::decode_list( + assert_eq!(Bencode::parse_list( ("e").as_bytes()).unwrap(), (Bencode::List(Vec::new()), 0) ); let str = "i42ee"; - assert_eq!(Bencode::decode_list( + assert_eq!(Bencode::parse_list( str.as_bytes()).unwrap(), ( Bencode::List(vec![ @@ -310,8 +310,8 @@ mod tests { str.len() - 1, ) ); - let str = format!("{}e", util_encode_bytes("hallo")); - assert_eq!(Bencode::decode_list( + let str = format!("{}e", util_compose_bytes("hallo")); + assert_eq!(Bencode::parse_list( str.as_bytes()).unwrap(), ( Bencode::List(vec![ @@ -320,8 +320,8 @@ mod tests { str.len() - 1, ) ); - let str = format!("{}{}e", util_encode_bytes("hallo"), "i42e"); - assert_eq!(Bencode::decode_list( + let str = format!("{}{}e", util_compose_bytes("hallo"), "i42e"); + assert_eq!(Bencode::parse_list( str.as_bytes()).unwrap(), ( Bencode::List(vec![ @@ -331,8 +331,8 @@ mod tests { str.len() - 1, ) ); - let str = format!("{}{}{}{}e", "i-17e", util_encode_bytes("hallo"), "i42e", util_encode_bytes("tschüssi💩")); - assert_eq!(Bencode::decode_list( + let str = format!("{}{}{}{}e", "i-17e", util_compose_bytes("hallo"), "i42e", util_compose_bytes("tschüssi💩")); + assert_eq!(Bencode::parse_list( str.as_bytes()).unwrap(), ( Bencode::List(vec![ @@ -348,7 +348,7 @@ mod tests { #[test] fn test_multi_list() { - assert_eq!(Bencode::decode_list( + assert_eq!(Bencode::parse_list( ("lelee").as_bytes()).unwrap(), (Bencode::List(vec![ Bencode::List(Vec::new()), @@ -356,8 +356,8 @@ mod tests { ]), 4) ); - let str = format!("l{}{}ee", util_encode_bytes("hallo"), "i42e"); - assert_eq!(Bencode::decode_list( + let str = format!("l{}{}ee", util_compose_bytes("hallo"), "i42e"); + assert_eq!(Bencode::parse_list( str.as_bytes()).unwrap(), (Bencode::List(vec![ Bencode::List(vec![ @@ -367,8 +367,8 @@ mod tests { ]), str.len() - 1) ); - let str = format!("l{}{}el{}{}{}ee", util_encode_bytes("hallo"), "i42e", "i17e", util_encode_bytes("tschüss💩"), "i33e"); - assert_eq!(Bencode::decode_list( + let str = format!("l{}{}el{}{}{}ee", util_compose_bytes("hallo"), "i42e", "i17e", util_compose_bytes("tschüss💩"), "i33e"); + assert_eq!(Bencode::parse_list( str.as_bytes()).unwrap(), (Bencode::List(vec![ Bencode::List(vec![ @@ -387,31 +387,31 @@ mod tests { #[test] fn test_list_str() { - assert_eq!(Bencode::decode( + assert_eq!(Bencode::parse( "le".as_bytes()).unwrap(), Bencode::List(Vec::new()) ); - assert_eq!(Bencode::decode( + assert_eq!(Bencode::parse( "li42ee".as_bytes()).unwrap(), Bencode::List(vec![ Bencode::Integer(42), ]) ); - assert_eq!(Bencode::decode( - (format!("l{}e", util_encode_bytes("hallo"))).as_bytes()).unwrap(), + assert_eq!(Bencode::parse( + (format!("l{}e", util_compose_bytes("hallo"))).as_bytes()).unwrap(), Bencode::List(vec![ Bencode::Bytes(ByteString::from_str("hallo")), ]) ); - assert_eq!(Bencode::decode( - (format!("l{}{}e", util_encode_bytes("hallo"), "i42e")).as_bytes()).unwrap(), + assert_eq!(Bencode::parse( + (format!("l{}{}e", util_compose_bytes("hallo"), "i42e")).as_bytes()).unwrap(), Bencode::List(vec![ Bencode::Bytes(ByteString::from_str("hallo")), Bencode::Integer(42), ]) ); - assert_eq!(Bencode::decode( - (format!("l{}{}{}{}e", "i-17e", util_encode_bytes("hallo"), "i42e", util_encode_bytes("tschüssi💩"))).as_bytes()).unwrap(), + assert_eq!(Bencode::parse( + (format!("l{}{}{}{}e", "i-17e", util_compose_bytes("hallo"), "i42e", util_compose_bytes("tschüssi💩"))).as_bytes()).unwrap(), Bencode::List(vec![ Bencode::Integer(-17), Bencode::Bytes(ByteString::from_str("hallo")), @@ -419,14 +419,14 @@ mod tests { Bencode::Bytes(ByteString::from_str("tschüssi💩")), ]) ); - assert_eq!(Bencode::decode("llelee".as_bytes()).unwrap(), + assert_eq!(Bencode::parse("llelee".as_bytes()).unwrap(), Bencode::List(vec![ Bencode::List(Vec::new()), Bencode::List(Vec::new()), ]), ); - let str = format!("ll{}{}ee", util_encode_bytes("hallo"), "i42e"); - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + let str = format!("ll{}{}ee", util_compose_bytes("hallo"), "i42e"); + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::List(vec![ Bencode::List(vec![ Bencode::Bytes(ByteString::from_str("hallo")), @@ -434,8 +434,8 @@ mod tests { ]), ]), ); - let str = format!("ll{}{}el{}{}{}ee", util_encode_bytes("hallo"), "i42e", "i17e", util_encode_bytes("tschüss💩"), "i33e"); - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + let str = format!("ll{}{}el{}{}{}ee", util_compose_bytes("hallo"), "i42e", "i17e", util_compose_bytes("tschüss💩"), "i33e"); + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::List(vec![ Bencode::List(vec![ Bencode::Bytes(ByteString::from_str("hallo")), @@ -448,8 +448,8 @@ mod tests { ]), ]), ); - let str = format!("ll{}{}ed{}{}{}{}ee", util_encode_bytes("hallo"), "i42e", util_encode_bytes("foo"), "i23e", util_encode_bytes("bar"), util_encode_bytes("baz")); - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + let str = format!("ll{}{}ed{}{}{}{}ee", util_compose_bytes("hallo"), "i42e", util_compose_bytes("foo"), "i23e", util_compose_bytes("bar"), util_compose_bytes("baz")); + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::List(vec![ Bencode::List(vec![ Bencode::Bytes(ByteString::from_str("hallo")), @@ -464,26 +464,26 @@ mod tests { } #[test] fn test_dict() { - assert_eq!(Bencode::decode_dict( + assert_eq!(Bencode::parse_dict( ("e").as_bytes()).unwrap(), (Bencode::Dict(HashMap::new()), 0) ); let str = "3:fooi42ee"; - assert_eq!(Bencode::decode_dict( + assert_eq!(Bencode::parse_dict( str.as_bytes()).unwrap(), (Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Integer(42)), ])), str.len() - 1) ); let str = "3:foo3:bare"; - assert_eq!(Bencode::decode_dict( + assert_eq!(Bencode::parse_dict( str.as_bytes()).unwrap(), (Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Bytes(ByteString::from_str("bar"))), ])), str.len() - 1) ); let str = "3:fooi42e3:bar3:baze"; - assert_eq!(Bencode::decode_dict( + assert_eq!(Bencode::parse_dict( str.as_bytes()).unwrap(), (Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Integer(42)), @@ -491,7 +491,7 @@ mod tests { ])), str.len() - 1) ); let str = "3:fooli42ei17ee3:bar3:baze"; - assert_eq!(Bencode::decode_dict( + assert_eq!(Bencode::parse_dict( str.as_bytes()).unwrap(), (Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::List( @@ -503,36 +503,36 @@ mod tests { #[test] fn test_dict_str() { - assert_eq!(Bencode::decode("de".as_bytes()).unwrap(), + assert_eq!(Bencode::parse("de".as_bytes()).unwrap(), Bencode::Dict(HashMap::new()) ); let str = "d3:fooi42ee"; - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Integer(42)), ])) ); - let str = format!("d{}i42ee", util_encode_bytes("💩")); - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + let str = format!("d{}i42ee", util_compose_bytes("💩")); + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::Dict(HashMap::from([ (ByteString::from_str("💩"), Bencode::Integer(42)), ])) ); let str = "d3:foo3:bare"; - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Bytes(ByteString::from_str("bar"))), ])) ); let str = "d3:fooi42e3:bar3:baze"; - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Integer(42)), (ByteString::from_str("bar"), Bencode::Bytes(ByteString::from_str("baz"))), ])) ); let str = "d3:fooli42ei17ee3:bar3:baze"; - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::List( vec![Bencode::Integer(42), Bencode::Integer(17)])), @@ -540,7 +540,7 @@ mod tests { ])) ); let str = "d3:foo3:bare"; - assert_eq!(Bencode::decode(str.as_bytes()).unwrap(), + assert_eq!(Bencode::parse(str.as_bytes()).unwrap(), Bencode::Dict(HashMap::from([ (ByteString::from_str("foo"), Bencode::Bytes(ByteString::from_str("bar"))), ]))