|
| 1 | +use anyhow::*; |
1 | 2 | use pegboard::protocol;
|
2 | 3 | use serde::{Deserialize, Serialize};
|
| 4 | +use tokio_util::codec::LengthDelimitedCodec; |
| 5 | +use serde::{de::DeserializeOwned, Serialize}; |
| 6 | +use bytes::Bytes; |
3 | 7 |
|
4 | 8 | #[derive(Debug, Serialize, Deserialize)]
|
5 | 9 | #[serde(rename_all = "snake_case", deny_unknown_fields)]
|
@@ -38,3 +42,38 @@ pub enum ActorState {
|
38 | 42 | Running,
|
39 | 43 | Exited { exit_code: Option<i32> },
|
40 | 44 | }
|
| 45 | + |
| 46 | +pub fn codec() -> LengthDelimitedCodec { |
| 47 | + LengthDelimitedCodec::builder() |
| 48 | + .length_field_type::<u32>() |
| 49 | + .length_field_length(4) |
| 50 | + // No offset |
| 51 | + .length_field_offset(0) |
| 52 | + // Header length is not included in the length calculation |
| 53 | + .length_adjustment(4) |
| 54 | + // Header is included in the returned bytes |
| 55 | + .num_skip(0) |
| 56 | + .new_codec() |
| 57 | +} |
| 58 | + |
| 59 | +pub fn encode_frame<T: Serialize>(payload: &T) -> Result<Vec<u8>> { |
| 60 | + let mut buf = Vec::with_capacity(4); |
| 61 | + buf.extend_from_slice(&[0u8; 4]); // header (currently unused) |
| 62 | + |
| 63 | + let mut cursor = Cursor::new(&mut buf); |
| 64 | + serde_json::to_writer(&mut cursor, payload)?; |
| 65 | + |
| 66 | + Ok(buf) |
| 67 | +} |
| 68 | + |
| 69 | +fn decode_frame<T: DeserializeOwned>(frame: &Vec<u8>) -> Result<([u8; 4], T)> { |
| 70 | + ensure!(frame.len() >= 4, "Frame too short"); |
| 71 | + |
| 72 | + // Extract the header (first 4 bytes) |
| 73 | + let header = [frame[0], frame[1], frame[2], frame[3]]; |
| 74 | + |
| 75 | + // Deserialize the rest of the frame (payload after the header) |
| 76 | + let payload = serde_json::from_slice(&frame[4..])?; |
| 77 | + |
| 78 | + Ok((header, payload)) |
| 79 | +} |
0 commit comments