metrale_storage/weight_peer/
wire.rs1use anyhow::{Context, Result, bail};
12
13use super::manifest::WeightManifest;
14
15fn read_u32<R: std::io::Read>(r: &mut R) -> Result<u32> {
16 let mut b = [0u8; 4];
17 r.read_exact(&mut b).context("read u32")?;
18 Ok(u32::from_le_bytes(b))
19}
20
21pub const MODEL_REQUEST_MAX: usize = 8192;
24
25pub fn write_model_request<W: std::io::Write>(w: &mut W, id: &str) -> Result<()> {
30 let bytes = id.as_bytes();
31 if bytes.is_empty() || bytes.len() > MODEL_REQUEST_MAX {
32 bail!("implausible model request length: {}", bytes.len());
33 }
34 w.write_all(&(bytes.len() as u32).to_le_bytes())?;
35 w.write_all(bytes)?;
36 Ok(())
37}
38
39pub fn read_model_request<R: std::io::Read>(r: &mut R) -> Result<String> {
45 let len = read_u32(r)? as usize;
46 if len == 0 || len > MODEL_REQUEST_MAX {
47 bail!("implausible model request length: {len}");
48 }
49 let mut buf = vec![0u8; len];
50 r.read_exact(&mut buf).context("read model request body")?;
51 String::from_utf8(buf).context("model request is not valid UTF-8")
52}
53
54pub fn write_weight_manifest<W: std::io::Write>(w: &mut W, m: &WeightManifest) -> Result<()> {
56 let json = serde_json::to_vec(m).context("serialize weight manifest")?;
57 w.write_all(&(json.len() as u32).to_le_bytes())?;
58 w.write_all(&json)?;
59 Ok(())
60}
61
62pub fn read_weight_manifest<R: std::io::Read>(r: &mut R) -> Result<WeightManifest> {
69 let len = read_u32(r)? as usize;
70 if len == 0 || len > 256 * 1024 * 1024 {
71 bail!("implausible weight manifest length: {len}");
72 }
73 let mut buf = vec![0u8; len];
74 r.read_exact(&mut buf)
75 .context("read weight manifest json")?;
76 let m: WeightManifest = serde_json::from_slice(&buf).context("parse weight manifest json")?;
77 if m.version != WeightManifest::VERSION {
78 bail!(
79 "weight manifest version {} != supported {}",
80 m.version,
81 WeightManifest::VERSION
82 );
83 }
84 if m.shard_files.len() != m.shard_lens.len() {
85 bail!(
86 "manifest shard_files ({}) / shard_lens ({}) length mismatch",
87 m.shard_files.len(),
88 m.shard_lens.len()
89 );
90 }
91 Ok(m)
92}
93
94#[cfg(test)]
95#[path = "wire_tests.rs"]
96mod tests;