-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
285 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
//! Byte string which helps with the deserialization. | ||
use core::{ | ||
borrow::{Borrow, BorrowMut}, | ||
cmp, fmt, | ||
ops::{Deref, DerefMut}, | ||
}; | ||
|
||
use serde::{ | ||
de::{SeqAccess, Visitor}, | ||
Deserialize, Deserializer, | ||
}; | ||
|
||
/// Byte string. | ||
/// | ||
/// Bencoded "strings" are not necessarily UTF-8 encoded values. | ||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
pub struct BString(Vec<u8>); | ||
|
||
impl AsRef<[u8]> for BString { | ||
fn as_ref(&self) -> &[u8] { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl AsMut<[u8]> for BString { | ||
fn as_mut(&mut self) -> &mut [u8] { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
impl Borrow<[u8]> for BString { | ||
fn borrow(&self) -> &[u8] { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl BorrowMut<[u8]> for BString { | ||
fn borrow_mut(&mut self) -> &mut [u8] { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
impl fmt::Debug for BString { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Debug::fmt(&self.0, f) | ||
} | ||
} | ||
|
||
impl Deref for BString { | ||
type Target = Vec<u8>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl DerefMut for BString { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for BString { | ||
fn from(value: &'a [u8]) -> Self { | ||
Self(Vec::from(value)) | ||
} | ||
} | ||
|
||
impl<'a> From<&'a str> for BString { | ||
fn from(value: &'a str) -> Self { | ||
Self(Vec::from(value)) | ||
} | ||
} | ||
|
||
impl From<String> for BString { | ||
fn from(value: String) -> Self { | ||
Self(Vec::from(value)) | ||
} | ||
} | ||
|
||
impl From<Vec<u8>> for BString { | ||
fn from(value: Vec<u8>) -> Self { | ||
Self(value) | ||
} | ||
} | ||
|
||
impl serde::Serialize for BString { | ||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: serde::Serializer, | ||
{ | ||
serializer.serialize_bytes(&self.0) | ||
} | ||
} | ||
|
||
struct BStringVisitor; | ||
|
||
impl<'de> Visitor<'de> for BStringVisitor { | ||
type Value = BString; | ||
|
||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
formatter.write_str("byte string") | ||
} | ||
|
||
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> | ||
where | ||
V: SeqAccess<'de>, | ||
{ | ||
let capacity = cmp::min(visitor.size_hint().unwrap_or_default(), 4096); | ||
let mut bytes = Vec::with_capacity(capacity); | ||
|
||
while let Some(b) = visitor.next_element()? { | ||
bytes.push(b); | ||
} | ||
|
||
Ok(BString::from(bytes)) | ||
} | ||
|
||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> { | ||
Ok(BString::from(v)) | ||
} | ||
|
||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> | ||
where | ||
E: serde::de::Error, | ||
{ | ||
Ok(BString::from(v)) | ||
} | ||
|
||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | ||
where | ||
E: serde::de::Error, | ||
{ | ||
Ok(BString::from(v)) | ||
} | ||
|
||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E> | ||
where | ||
E: serde::de::Error, | ||
{ | ||
Ok(BString::from(v)) | ||
} | ||
} | ||
|
||
impl<'de> Deserialize<'de> for BString { | ||
fn deserialize<D>(deserializer: D) -> Result<BString, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
deserializer.deserialize_byte_buf(BStringVisitor) | ||
} | ||
} | ||
|
||
impl BString { | ||
/// Returns the inner vector. | ||
#[inline] | ||
#[must_use] | ||
pub fn into_vec(self) -> Vec<u8> { | ||
self.0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.