Skip to main content

tf_demo_parser/demo/message/
classinfo.rs

1use bitbuffer::{BitRead, BitReadSized, LittleEndian};
2#[cfg(feature = "write")]
3use bitbuffer::{BitWrite, BitWriteSized, BitWriteStream};
4use serde::{Deserialize, Serialize};
5
6use crate::demo::message::stringtable::log_base2;
7use crate::{ReadResult, Stream};
8use std::cmp::min;
9
10#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
11#[derive(BitReadSized, Debug, PartialEq, Serialize, Deserialize, Clone)]
12#[cfg_attr(feature = "write", derive(BitWriteSized))]
13pub struct ClassInfoEntry {
14    #[size = "input_size"]
15    class_id: u16,
16    class_name: String,
17    table_name: String,
18}
19
20#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
21#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
22pub struct ClassInfoMessage {
23    count: u16,
24    create: bool,
25    entries: Vec<ClassInfoEntry>,
26}
27
28impl BitRead<'_, LittleEndian> for ClassInfoMessage {
29    fn read(stream: &mut Stream) -> ReadResult<Self> {
30        let count: u16 = stream.read()?;
31        let create: bool = stream.read()?;
32        let entries = if !create {
33            let mut entries = Vec::with_capacity(min(count, 128) as usize);
34            let bits = log_base2(count) + 1;
35            for _ in 0..count {
36                entries.push(stream.read_sized(bits as usize)?);
37            }
38            entries
39        } else {
40            Vec::new()
41        };
42
43        Ok(ClassInfoMessage {
44            count,
45            create,
46            entries,
47        })
48    }
49}
50
51#[cfg(feature = "write")]
52impl BitWrite<LittleEndian> for ClassInfoMessage {
53    fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
54        self.count.write(stream)?;
55        self.create.write(stream)?;
56        if !self.create {
57            let bits = log_base2(self.entries.len()) as usize + 1;
58            for entry in self.entries.iter() {
59                entry.write_sized(stream, bits)?;
60            }
61        }
62
63        Ok(())
64    }
65}
66
67#[test]
68#[cfg(feature = "write")]
69fn test_class_info_roundtrip() {
70    crate::test_roundtrip_write(ClassInfoMessage {
71        count: 8,
72        create: true,
73        entries: Vec::new(),
74    });
75    crate::test_roundtrip_write(ClassInfoMessage {
76        count: 3,
77        create: false,
78        entries: vec![
79            ClassInfoEntry {
80                class_id: 0,
81                class_name: "foo1".to_string(),
82                table_name: "bar1".to_string(),
83            },
84            ClassInfoEntry {
85                class_id: 1,
86                class_name: "foo2".to_string(),
87                table_name: "bar2".to_string(),
88            },
89            ClassInfoEntry {
90                class_id: 2,
91                class_name: "foo3".to_string(),
92                table_name: "bar3".to_string(),
93            },
94        ],
95    });
96}