luanti_protocol/types/
binary.rs

1use std::marker::PhantomData;
2
3use anyhow::bail;
4
5use crate::wire::{
6    deser::{Deserialize, DeserializeError, DeserializeResult, Deserializer},
7    ser::{Serialize, SerializeResult, Serializer},
8};
9
10// Wrapped in a String (really a BinaryData16) with a 16-bit length
11#[derive(Debug, Clone, PartialEq)]
12pub struct Wrapped16<T> {
13    phantom: PhantomData<T>,
14}
15
16impl<T: Serialize> Serialize for Wrapped16<T> {
17    type Input = T::Input;
18    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
19        let marker = ser.write_marker(2)?;
20        <T as Serialize>::serialize(value, ser)?;
21        let len: u16 = u16::try_from(ser.marker_distance(&marker))?;
22        ser.set_marker(marker, &len.to_be_bytes()[..])?;
23        Ok(())
24    }
25}
26
27impl<T: Deserialize> Deserialize for Wrapped16<T> {
28    type Output = T::Output;
29    fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
30        let len = u16::deserialize(deser)?;
31        let mut restricted_deser = deser.slice(len as usize)?;
32        <T as Deserialize>::deserialize(&mut restricted_deser)
33    }
34}
35
36// Wrapped in a String (really a BinaryData16) with a 16-bit length
37#[derive(Debug, Clone, PartialEq)]
38pub struct Wrapped32<T> {
39    phantom: PhantomData<T>,
40}
41
42impl<T: Serialize> Serialize for Wrapped32<T> {
43    type Input = T::Input;
44    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
45        let marker = ser.write_marker(4)?;
46        <T as Serialize>::serialize(value, ser)?;
47        let len: u32 = u32::try_from(ser.marker_distance(&marker))?;
48        ser.set_marker(marker, &len.to_be_bytes()[..])?;
49        Ok(())
50    }
51}
52
53impl<T: Deserialize> Deserialize for Wrapped32<T> {
54    type Output = T::Output;
55    fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
56        let len = u32::deserialize(deser)?;
57        let mut restricted_deser = deser.slice(len as usize)?;
58        <T as Deserialize>::deserialize(&mut restricted_deser)
59    }
60}
61
62#[derive(Debug, Clone, PartialEq)]
63pub struct BinaryData16;
64
65impl Serialize for BinaryData16 {
66    type Input = Vec<u8>;
67    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
68        u16::serialize(&u16::try_from(value.len())?, ser)?;
69        ser.write_bytes(value)?;
70        Ok(())
71    }
72}
73
74impl Deserialize for BinaryData16 {
75    type Output = Vec<u8>;
76    fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
77        let num_bytes = u16::deserialize(deser)? as usize;
78        Ok(Vec::from(deser.take(num_bytes)?))
79    }
80}
81
82/// Binary data preceded by a U32 size
83#[derive(Debug, Clone, PartialEq)]
84pub struct BinaryData32;
85
86impl Serialize for BinaryData32 {
87    type Input = Vec<u8>;
88    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
89        u32::serialize(&u32::try_from(value.len())?, ser)?;
90        ser.write_bytes(value)?;
91        Ok(())
92    }
93}
94
95impl Deserialize for BinaryData32 {
96    type Output = Vec<u8>;
97    fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
98        let num_bytes = u32::deserialize(deser)? as usize;
99        Ok(Vec::from(deser.take(num_bytes)?))
100    }
101}
102
103#[derive(Debug, Clone, PartialEq)]
104pub struct FixedArray<const COUNT: usize, T>
105where
106    T: Serialize<Input = T>,
107    T: Deserialize<Output = T>,
108{
109    phantom: PhantomData<T>,
110}
111
112impl<const COUNT: usize, T> Serialize for FixedArray<COUNT, T>
113where
114    T: Serialize<Input = T>,
115    T: Deserialize<Output = T>,
116{
117    type Input = [T; COUNT];
118    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
119        for ent in value {
120            <T as Serialize>::serialize(ent, ser)?;
121        }
122        Ok(())
123    }
124}
125
126impl<const COUNT: usize, T> Deserialize for FixedArray<COUNT, T>
127where
128    T: Serialize<Input = T>,
129    T: Deserialize<Output = T>,
130{
131    type Output = [T; COUNT];
132    fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
133        let mut entries = Vec::with_capacity(COUNT);
134        for _ in 0..COUNT {
135            entries.push(<T as Deserialize>::deserialize(deser)?);
136        }
137        match entries.try_into() {
138            Ok(entries) => Ok(entries),
139            Err(_) => bail!(DeserializeError::InvalidValue("FixedArray bug".into())),
140        }
141    }
142}