Skip to content

Commit c20b453

Browse files
committed
Add encode_into for reusing a bufferfish
1 parent c1585a9 commit c20b453

File tree

3 files changed

+138
-3
lines changed

3 files changed

+138
-3
lines changed

rust/bufferfish-core/src/encodable.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ pub trait Encodable {
1414

1515
Ok(bf)
1616
}
17+
18+
/// Encode this type into a provided `Bufferfish` buffer.
19+
///
20+
/// This is useful when you want to reuse an existing buffer to avoid
21+
/// allocations.
22+
fn encode_into(self, bf: &mut Bufferfish) -> Result<(), BufferfishError>
23+
where
24+
Self: Sized,
25+
{
26+
self.encode(bf)
27+
}
1728
}
1829

1930
impl Encodable for u8 {

rust/bufferfish-derive/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ pub fn bufferfish_impl_encodable(input: proc_macro::TokenStream) -> proc_macro::
6767

6868
Ok(bf)
6969
}
70+
71+
fn encode_into(self, bf: &mut bufferfish::Bufferfish) -> Result<(), bufferfish::BufferfishError>
72+
where
73+
Self: Sized,
74+
{
75+
#packet_id_snippet
76+
self.encode(bf)
77+
}
7078
}
7179
};
7280

rust/bufferfish/src/lib.rs

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ mod tests {
552552
}
553553

554554
#[test]
555-
fn test_encode_struct() {
555+
fn test_to_bufferfish_struct() {
556556
use bufferfish_core as bufferfish;
557557
use bufferfish_core::Encodable;
558558

@@ -586,7 +586,7 @@ mod tests {
586586
}
587587

588588
#[test]
589-
fn test_encode_array() {
589+
fn test_to_bufferfish_array() {
590590
use bufferfish_core as bufferfish;
591591
use bufferfish_core::Encodable;
592592

@@ -619,7 +619,7 @@ mod tests {
619619
}
620620

621621
#[test]
622-
fn test_encode_enums() {
622+
fn test_to_bufferfish_enums() {
623623
use bufferfish_core as bufferfish;
624624
use bufferfish_core::Encodable;
625625

@@ -665,6 +665,122 @@ mod tests {
665665
assert_eq!(bf.as_ref(), &[0, 0, 0]);
666666
}
667667

668+
#[test]
669+
fn test_encode_into_struct() {
670+
use bufferfish_core as bufferfish;
671+
use bufferfish_core::Encodable;
672+
673+
#[derive(Encode)]
674+
#[bufferfish(0_u16)]
675+
struct JoinPacket {
676+
user: User,
677+
}
678+
679+
#[derive(Encode)]
680+
struct User {
681+
id: u32,
682+
name: String,
683+
}
684+
685+
let mut bf = Bufferfish::new();
686+
let user = User {
687+
id: 0,
688+
name: "Bufferfish".to_string(),
689+
};
690+
let packet = JoinPacket { user };
691+
692+
packet.encode_into(&mut bf).unwrap();
693+
694+
assert_eq!(
695+
bf.as_ref(),
696+
&[
697+
0, 0, 0, 0, 0, 0, 0, 10, 66, 117, 102, 102, 101, 114, 102, 105, 115, 104
698+
]
699+
);
700+
}
701+
702+
#[test]
703+
fn test_encode_into_array() {
704+
use bufferfish_core as bufferfish;
705+
use bufferfish_core::Encodable;
706+
707+
#[derive(Encode)]
708+
struct User {
709+
id: u32,
710+
name: String,
711+
}
712+
713+
let users = vec![
714+
User {
715+
id: 0,
716+
name: "Bufferfish".to_string(),
717+
},
718+
User {
719+
id: 1,
720+
name: "Bufferfish2".to_string(),
721+
},
722+
];
723+
724+
let mut bf = Bufferfish::new();
725+
users.encode_into(&mut bf).unwrap();
726+
727+
assert_eq!(
728+
bf.as_ref(),
729+
&[
730+
0, 2, 0, 0, 0, 0, 0, 10, 66, 117, 102, 102, 101, 114, 102, 105, 115, 104, 0, 0, 0,
731+
1, 0, 11, 66, 117, 102, 102, 101, 114, 102, 105, 115, 104, 50,
732+
]
733+
);
734+
}
735+
736+
#[test]
737+
fn test_encode_into_enums() {
738+
use bufferfish_core as bufferfish;
739+
use bufferfish_core::Encodable;
740+
741+
#[derive(Encode, Clone, Copy)]
742+
enum PacketId {
743+
Join,
744+
}
745+
746+
impl From<PacketId> for u16 {
747+
fn from(value: PacketId) -> Self {
748+
match value {
749+
PacketId::Join => 0,
750+
}
751+
}
752+
}
753+
754+
#[derive(Encode)]
755+
#[bufferfish(PacketId::Join)]
756+
struct JoinPacket {
757+
class: Class,
758+
}
759+
760+
#[derive(Encode, Clone, Copy)]
761+
#[repr(u8)]
762+
enum Class {
763+
Warrior,
764+
}
765+
766+
impl From<Class> for u8 {
767+
fn from(value: Class) -> Self {
768+
match value {
769+
Class::Warrior => 0,
770+
}
771+
}
772+
}
773+
774+
let mut bf = Bufferfish::new();
775+
let packet = JoinPacket {
776+
class: Class::Warrior,
777+
};
778+
779+
packet.encode_into(&mut bf).unwrap();
780+
781+
assert_eq!(bf.as_ref(), &[0, 0, 0]);
782+
}
783+
668784
#[test]
669785
fn test_decode_struct() {
670786
use bufferfish_core as bufferfish;

0 commit comments

Comments
 (0)