1
use std::time::Duration;
2

            
3
use super::Request;
4

            
5
pub struct Oack {
6
    pub block_size:	Option<u16>,
7
    pub timeout:	Option<std::time::Duration>,
8
    pub window_size:	Option<u16>,
9
    pub tsize:		Option<u64>,
10
}
11

            
12
impl Oack {
13
    pub fn from_request(req: &Request<'_>) -> Self {
14
	Self {
15
	    block_size:		req.block_size,
16
	    timeout:		req.timeout,
17
	    window_size:	req.window_size,
18
	    tsize:		req.tsize,
19
	}
20
    }
21

            
22
    pub fn update_block_size<F>(&mut self, max_val: u16, update_fn: F)
23
    where
24
	F: FnOnce(u16)
25
    {
26
	if let Some(sz) = self.block_size {
27
	    let v = sz.min(max_val);
28
	    self.block_size = Some(v);
29
	    update_fn(v)
30
	}
31
    }
32

            
33
    pub fn update_window_size<F>(&mut self, max_val: u16, update_fn: F)
34
    where
35
	F: FnOnce(u16)
36
    {
37
	if let Some(sz) = self.window_size {
38
	    let v = sz.min(max_val);
39
	    self.window_size = Some(v);
40
	    update_fn(v);
41
	}
42
    }
43

            
44
    pub fn update_timeout<F>(&mut self, update_fn: F)
45
    where
46
	F: FnOnce(Duration)
47
    {
48
	if let Some(tm) = self.timeout {
49
	    update_fn(tm);
50
	}
51
    }
52

            
53
    pub fn update_tsize(&mut self, new_sz: Option<u64>)
54
    {
55
	if let Some(sz) = self.tsize {
56
	    assert_eq!(sz, 0);
57
	    self.tsize = new_sz;
58
	}
59
    }
60

            
61
    fn append_option<V: Into<u64>>(msg: &mut Vec<u8>, id: &[u8], value: V)
62
    {
63
	msg.extend(id);
64
	msg.push(0);
65
	msg.extend(value.into().to_string().as_bytes());
66
	msg.push(0);
67
    }
68

            
69
    pub fn fill_buf(self, msg: &mut Vec::<u8>)
70
    {
71
	msg.extend([0, 6]);
72

            
73
	if let Some(sz) = self.block_size {
74
	    Self::append_option(msg, b"blksize", sz);
75
	}
76

            
77
	if let Some(sz) = self.window_size {
78
	    Self::append_option(msg, b"windowsize", sz);
79
	}
80

            
81
	if let Some(sz) = self.tsize {
82
	    Self::append_option(msg, b"tsize", sz);
83
	}
84

            
85
	if let Some(to) = self.timeout {
86
	    Self::append_option(msg, b"timeout", to.as_secs());
87
	}
88
    }
89
}