Skip to content

Commit f6b8694

Browse files
committed
cleanup const support
make BytesAdapter externally implementable, propagate errors from BytesAdapter decode fn
1 parent a64606a commit f6b8694

File tree

2 files changed

+93
-55
lines changed

2 files changed

+93
-55
lines changed

Diff for: src/encoding.rs

+64-45
Original file line numberDiff line numberDiff line change
@@ -873,54 +873,63 @@ pub mod string {
873873
}
874874
}
875875

876-
pub trait BytesAdapter: sealed::BytesAdapter + sealed::Newable {}
876+
pub trait BytesAdapter: Sized + 'static {
877+
/// Create a new instance (required as `Default` is not available for all types)
878+
fn new() -> Self;
877879

878-
mod sealed {
879-
use super::{Buf, BufMut};
880-
881-
pub trait BytesAdapter: Sized + 'static {
882-
fn len(&self) -> usize;
880+
fn len(&self) -> usize;
883881

884-
/// Replace contents of this buffer with the contents of another buffer.
885-
fn replace_with<B>(&mut self, buf: B)
886-
where
887-
B: Buf;
882+
/// Replace contents of this buffer with the contents of another buffer.
883+
fn replace_with<B>(&mut self, buf: B) -> Result<(), DecodeError>
884+
where
885+
B: Buf;
888886

889-
/// Appends this buffer to the (contents of) other buffer.
890-
fn append_to<B>(&self, buf: &mut B)
891-
where
892-
B: BufMut;
887+
/// Appends this buffer to the (contents of) other buffer.
888+
fn append_to<B>(&self, buf: &mut B)
889+
where
890+
B: BufMut;
893891

894-
fn is_empty(&self) -> bool {
895-
self.len() == 0
896-
}
892+
fn is_empty(&self) -> bool {
893+
self.len() == 0
897894
}
898895

899-
/// Alternate to `Default` as this is not (yet?) implemented over [T; N]
900-
/// (and cannot be automatic as `Default` _is_ implemented for N < 32)
896+
fn clear(&mut self);
897+
}
898+
899+
mod sealed {
901900
pub trait Newable: Sized {
902901
fn new() -> Self;
903902
}
904-
}
905903

906-
impl BytesAdapter for Bytes {}
904+
impl<T: super::BytesAdapter> Newable for T {
905+
fn new() -> Self {
906+
super::BytesAdapter::new()
907+
}
908+
}
909+
910+
impl Newable for String {
911+
fn new() -> Self {
912+
Default::default()
913+
}
914+
}
915+
}
907916

908-
impl sealed::Newable for Bytes {
917+
impl BytesAdapter for Bytes {
909918
fn new() -> Self {
910919
Default::default()
911920
}
912-
}
913921

914-
impl sealed::BytesAdapter for Bytes {
915922
fn len(&self) -> usize {
916923
Buf::remaining(self)
917924
}
918925

919-
fn replace_with<B>(&mut self, mut buf: B)
926+
fn replace_with<B>(&mut self, mut buf: B) -> Result<(), DecodeError>
920927
where
921928
B: Buf,
922929
{
923930
*self = buf.copy_to_bytes(buf.remaining());
931+
932+
Ok(())
924933
}
925934

926935
fn append_to<B>(&self, buf: &mut B)
@@ -929,28 +938,30 @@ impl sealed::BytesAdapter for Bytes {
929938
{
930939
buf.put(self.clone())
931940
}
932-
}
933941

934-
impl BytesAdapter for Vec<u8> {}
942+
fn clear(&mut self) {
943+
Bytes::clear(self)
944+
}
945+
}
935946

936-
impl sealed::Newable for Vec<u8> {
947+
impl BytesAdapter for Vec<u8> {
937948
fn new() -> Self {
938949
Default::default()
939950
}
940-
}
941951

942-
impl sealed::BytesAdapter for Vec<u8> {
943952
fn len(&self) -> usize {
944953
Vec::len(self)
945954
}
946955

947-
fn replace_with<B>(&mut self, buf: B)
956+
fn replace_with<B>(&mut self, buf: B) -> Result<(), DecodeError>
948957
where
949958
B: Buf,
950959
{
951-
self.clear();
960+
Vec::clear(self);
952961
self.reserve(buf.remaining());
953962
self.put(buf);
963+
964+
Ok(())
954965
}
955966

956967
fn append_to<B>(&self, buf: &mut B)
@@ -959,26 +970,32 @@ impl sealed::BytesAdapter for Vec<u8> {
959970
{
960971
buf.put(self.as_slice())
961972
}
962-
}
963973

964-
impl<const N: usize> BytesAdapter for [u8; N] {}
974+
fn clear(&mut self) {
975+
Vec::clear(self)
976+
}
977+
}
965978

966-
impl<const N: usize> sealed::Newable for [u8; N] {
979+
impl<const N: usize> BytesAdapter for [u8; N] {
967980
fn new() -> Self {
968981
[0u8; N]
969982
}
970-
}
971983

972-
impl<const N: usize> sealed::BytesAdapter for [u8; N] {
973984
fn len(&self) -> usize {
974985
N
975986
}
976987

977-
fn replace_with<B>(&mut self, buf: B)
988+
fn replace_with<B>(&mut self, buf: B) -> Result<(), DecodeError>
978989
where
979990
B: Buf,
980991
{
981-
self.copy_from_slice(buf.chunk())
992+
if buf.remaining() != N {
993+
return Err(DecodeError::new("invalid byte array length"));
994+
}
995+
996+
self.copy_from_slice(buf.chunk());
997+
998+
Ok(())
982999
}
9831000

9841001
fn append_to<B>(&self, buf: &mut B)
@@ -987,11 +1004,11 @@ impl<const N: usize> sealed::BytesAdapter for [u8; N] {
9871004
{
9881005
buf.put(&self[..])
9891006
}
990-
}
9911007

992-
impl sealed::Newable for String {
993-
fn new() -> Self {
994-
Default::default()
1008+
fn clear(&mut self) {
1009+
for b in &mut self[..] {
1010+
*b = 0;
1011+
}
9951012
}
9961013
}
9971014

@@ -1037,7 +1054,8 @@ pub mod bytes {
10371054
// This is intended for A and B both being Bytes so it is zero-copy.
10381055
// Some combinations of A and B types may cause a double-copy,
10391056
// in which case merge_one_copy() should be used instead.
1040-
value.replace_with(buf.copy_to_bytes(len));
1057+
value.replace_with(buf.copy_to_bytes(len))?;
1058+
10411059
Ok(())
10421060
}
10431061

@@ -1059,7 +1077,8 @@ pub mod bytes {
10591077
let len = len as usize;
10601078

10611079
// If we must copy, make sure to copy only once.
1062-
value.replace_with(buf.take(len));
1080+
value.replace_with(buf.take(len))?;
1081+
10631082
Ok(())
10641083
}
10651084

Diff for: tests/src/derive_const.rs

+29-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,41 @@
1-
use core::fmt::Debug;
2-
use prost::Message;
1+
use prost::{encoding::BytesAdapter, Message};
32

4-
/// Const array container
3+
// NOTE: [Message] still requires [Default], which is not implemented for [u8; N],
4+
// so this will only work directly for [u8; <=32] for the moment...
5+
// see: https://github.com/rust-lang/rust/issues/61415
6+
7+
/// Const array container A
58
#[derive(Clone, PartialEq, Message)]
6-
pub struct TestArray {
7-
#[prost(message, required, tag = "1")]
9+
pub struct TestA {
10+
#[prost(bytes, required, tag = "1")]
811
pub b: [u8; 3],
912
}
1013

14+
/// Const array container B
15+
#[derive(Clone, PartialEq, Message)]
16+
pub struct TestB {
17+
#[prost(bytes, required, tag = "1")]
18+
pub b: [u8; 4],
19+
}
20+
21+
// Test valid encode/decode
1122
#[test]
12-
fn encode_decode_const_array() {
13-
let t = TestArray { b: [1, 2, 3] };
23+
fn const_array_encode_decode() {
24+
let t = TestA { b: [1, 2, 3] };
1425

1526
let buff = t.encode_to_vec();
1627

17-
let b = TestArray::decode(&*buff).unwrap();
28+
let t1 = TestA::decode(&*buff).unwrap();
1829

19-
assert_eq!(a, b);
30+
assert_eq!(t, t1);
31+
}
32+
33+
// test encode/decode length mismatch
34+
#[test]
35+
fn const_array_length_mismatch() {
36+
let t = TestA { b: [1, 2, 3] };
37+
38+
let buff = t.encode_to_vec();
2039

21-
panic!("whjoops");
40+
assert!(TestB::decode(&*buff).is_err());
2241
}

0 commit comments

Comments
 (0)