buntrail_protocol/
negotiation.rs1use crate::{frame::*, types::*};
2pub const INITIAL_CREDIT: usize = 512 * 1024;
3pub const CAPABILITIES: &[&str] = &[
4 "git.repository.v1",
5 "container.binding.v1",
6 "leases",
7 "leases.retirement",
8 "leases.observe",
9 "operations",
10 "file.read",
11 "file.resolve",
12 "file.remove",
13 "file.save",
14 "file.save_proof",
15 "services",
16 "git.read",
17 "git.existing",
18 "git.worktree_proof",
19 "git.original_lookup",
20 "terminal",
21 "terminal.ordered_controls",
22];
23#[derive(Clone)]
24pub struct Negotiated {
25 pub minor: u32,
26 pub capabilities: Vec<String>,
27 pub max_header: usize,
28 pub max_payload: usize,
29}
30impl Negotiated {
31 pub fn from_hello(header: &Header) -> Result<Self, &'static str> {
32 header.validate(0, None)?;
33 let Message::Hello {
34 capabilities,
35 max_header,
36 max_payload,
37 } = &header.message
38 else {
39 return Err("hello required");
40 };
41 if *max_header < 1024 || *max_payload < 65536 {
42 return Err("limits cannot support required control and chunk frames");
43 }
44 Ok(Self {
45 minor: MINOR,
46 capabilities: CAPABILITIES
47 .iter()
48 .filter(|c| capabilities.iter().any(|v| v == **c))
49 .map(|s| s.to_string())
50 .collect(),
51 max_header: *max_header as usize,
52 max_payload: *max_payload as usize,
53 })
54 }
55 pub fn supports(&self, name: &str) -> bool {
56 self.capabilities.iter().any(|s| s == name)
57 }
58}