y_octo/protocol/
doc.rs

1use super::*;
2
3// doc sync message
4#[derive(Debug, Clone, PartialEq)]
5#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
6pub enum DocMessage {
7    // state vector
8    // TODO: temporarily skipped in the test, because yrs decoding needs to ensure that the update in step1 is the
9    // correct state vector binary       and any data can be included in our implementation (we will ensure the
10    // correctness of encoding and decoding in the subsequent decoding process)
11    #[cfg_attr(test, proptest(skip))]
12    Step1(Vec<u8>),
13    // update
14    Step2(Vec<u8>),
15    // update
16    Update(Vec<u8>),
17}
18
19const DOC_MESSAGE_STEP1: u64 = 0;
20const DOC_MESSAGE_STEP2: u64 = 1;
21const DOC_MESSAGE_UPDATE: u64 = 2;
22
23pub fn read_doc_message(input: &[u8]) -> IResult<&[u8], DocMessage> {
24    let (tail, step) = read_var_u64(input)?;
25
26    match step {
27        DOC_MESSAGE_STEP1 => {
28            let (tail, sv) = read_var_buffer(tail)?;
29            // TODO: decode state vector
30            Ok((tail, DocMessage::Step1(sv.into())))
31        }
32        DOC_MESSAGE_STEP2 => {
33            let (tail, update) = read_var_buffer(tail)?;
34            // TODO: decode update
35            Ok((tail, DocMessage::Step2(update.into())))
36        }
37        DOC_MESSAGE_UPDATE => {
38            let (tail, update) = read_var_buffer(tail)?;
39            // TODO: decode update
40            Ok((tail, DocMessage::Update(update.into())))
41        }
42        _ => Err(nom::Err::Error(Error::new(input, ErrorKind::Tag))),
43    }
44}
45
46pub fn write_doc_message<W: Write>(buffer: &mut W, msg: &DocMessage) -> Result<(), IoError> {
47    match msg {
48        DocMessage::Step1(sv) => {
49            write_var_u64(buffer, DOC_MESSAGE_STEP1)?;
50            write_var_buffer(buffer, sv)?;
51        }
52        DocMessage::Step2(update) => {
53            write_var_u64(buffer, DOC_MESSAGE_STEP2)?;
54            write_var_buffer(buffer, update)?;
55        }
56        DocMessage::Update(update) => {
57            write_var_u64(buffer, DOC_MESSAGE_UPDATE)?;
58            write_var_buffer(buffer, update)?;
59        }
60    }
61
62    Ok(())
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_doc_message() {
71        let messages = [
72            DocMessage::Step1(vec![0x01, 0x02, 0x03]),
73            DocMessage::Step2(vec![0x04, 0x05, 0x06]),
74            DocMessage::Update(vec![0x07, 0x08, 0x09]),
75        ];
76
77        for msg in messages {
78            let mut buffer = Vec::new();
79
80            write_doc_message(&mut buffer, &msg).unwrap();
81            let (tail, decoded) = read_doc_message(&buffer).unwrap();
82
83            assert_eq!(tail.len(), 0);
84            assert_eq!(decoded, msg);
85        }
86
87        // test invalid msg
88        {
89            let mut buffer = Vec::new();
90            let msg = DocMessage::Step1(vec![0x01, 0x02, 0x03]);
91
92            write_doc_message(&mut buffer, &msg).unwrap();
93            buffer[0] = 0xff; // Inject error in message tag
94            let res = read_doc_message(&buffer);
95
96            match res.as_ref().unwrap_err() {
97                nom::Err::Error(error) => assert_eq!(error.code, ErrorKind::Tag),
98                _ => panic!("Expected error ErrorKind::Tag, but got {:?}", res),
99            }
100        }
101    }
102}