Skip to content

Commit a83c1ae

Browse files
authored
Merge pull request #27 from webmaster128/add-into_x
Add Anybuf::into_x
2 parents b93c8de + 86c7cf2 commit a83c1ae

3 files changed

Lines changed: 58 additions & 1 deletion

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ std = []
1818

1919
[dev-dependencies]
2020
hex-literal = "0.4.1"
21+
bytes = "1.10.1"

src/anybuf.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ enum WireType {
2121
}
2222

2323
/// A minmal protobuf encoder.
24-
#[derive(Default)]
24+
#[derive(Default, Clone)]
2525
pub struct Anybuf {
2626
output: Vec<u8>,
2727
}
@@ -519,6 +519,35 @@ impl Anybuf {
519519
self.output
520520
}
521521

522+
/// Takes the instance and returns the protobuf bytes.
523+
/// The return type is defined by the caller and can be anything that implements `From<Vec<u8>>`.
524+
/// Roughly speaking, `data.into_x()` is the same as calling `data.into_vec().into()`.
525+
///
526+
/// ## Examples
527+
///
528+
/// We create an Anybuf instance and then convert it into [Bytes], which just serves
529+
/// as an example for a type that can be created from `Vec<u8>`.
530+
///
531+
/// ```
532+
/// # use anybuf::Anybuf;
533+
/// use bytes::Bytes;
534+
///
535+
/// // variable type known
536+
/// let serialized: Bytes = Anybuf::new()
537+
/// .append_repeated_int64(4, &[-30, 0, 17])
538+
/// .into_x();
539+
///
540+
/// // explicit type parameter
541+
/// let serialized = Anybuf::new()
542+
/// .append_repeated_int64(4, &[-30, 0, 17])
543+
/// .into_x::<Bytes>();
544+
/// ```
545+
///
546+
/// [Bytes]: https://docs.rs/bytes/latest/bytes/struct.Bytes.html
547+
pub fn into_x<T: From<Vec<u8>>>(self) -> T {
548+
T::from(self.output)
549+
}
550+
522551
fn append_tag(&mut self, field_number: u32, field_type: WireType) {
523552
// The top 3 bits of a field number must be unset, ie.e this shift is safe for valid field numbers
524553
// "The smallest field number you can specify is 1, and the largest is 2^29-1, or 536,870,911"
@@ -1027,4 +1056,24 @@ mod tests {
10271056
let data = Anybuf::new().append_repeated_message(11, &owned);
10281057
assert_eq!(data.into_vec(), hex!("5a0208015a0208025a020803"));
10291058
}
1059+
1060+
#[test]
1061+
fn into_x_works() {
1062+
use bytes::Bytes;
1063+
1064+
let data = Anybuf::new()
1065+
.append_string(1, "hello, world")
1066+
.append_repeated_int64(2, &[-30, 0, 17]);
1067+
let vec = data.clone().into_vec();
1068+
let bytes: Bytes = data.into_x();
1069+
assert_eq!(bytes, vec);
1070+
1071+
let serialized = Anybuf::new()
1072+
.append_repeated_int64(4, &[-30, 0, 17])
1073+
.into_x::<Bytes>();
1074+
assert_eq!(
1075+
serialized,
1076+
b" \xe2\xff\xff\xff\xff\xff\xff\xff\xff\x01 \0 \x11" as &[u8]
1077+
);
1078+
}
10301079
}

0 commit comments

Comments
 (0)