Coverage Report

Created: 2026-08-14 08:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rmp-0.8.15/src/decode/ext.rs
Line
Count
Source
1
use super::{read_marker, RmpRead, ValueReadError};
2
use crate::Marker;
3
4
/// Attempts to read exactly 3 bytes from the given reader and interpret them as a fixext1 type
5
/// with data attached.
6
///
7
/// According to the MessagePack specification, a fixext1 stores an integer and a byte array whose
8
/// length is 1 byte. Its marker byte is `0xd4`.
9
///
10
/// Note, that this function copies a byte array from the reader to the output `u8` variable.
11
///
12
/// # Errors
13
///
14
/// This function will return `ValueReadError` on any I/O error while reading either the marker or
15
/// the data.
16
///
17
/// # Note
18
///
19
/// This function will silently retry on every EINTR received from the underlying `Read` until
20
/// successful read.
21
0
pub fn read_fixext1<R: RmpRead>(rd: &mut R) -> Result<(i8, u8), ValueReadError<R::Error>> {
22
0
    match read_marker(rd)? {
23
        Marker::FixExt1 => {
24
0
            let ty = rd.read_data_i8()?;
25
0
            let data = rd.read_data_u8()?;
26
0
            Ok((ty, data))
27
        },
28
0
        marker => Err(ValueReadError::TypeMismatch(marker)),
29
    }
30
0
}
31
32
/// Attempts to read exactly 4 bytes from the given reader and interpret them as a fixext2 type
33
/// with data attached.
34
///
35
/// According to the MessagePack specification, a fixext2 stores an integer and a byte array whose
36
/// length is 2 bytes. Its marker byte is `0xd5`.
37
///
38
/// Note, that this function copies a byte array from the reader to the output buffer, which is
39
/// unlikely if you want zero-copy functionality.
40
///
41
/// # Errors
42
///
43
/// This function will return `ValueReadError` on any I/O error while reading either the marker or
44
/// the data.
45
0
pub fn read_fixext2<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 2]), ValueReadError<R::Error>> {
46
0
    match read_marker(rd)? {
47
        Marker::FixExt2 => {
48
0
            let mut buf = [0; 2];
49
0
            read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
50
        },
51
0
        marker => Err(ValueReadError::TypeMismatch(marker)),
52
    }
53
0
}
54
55
/// Attempts to read exactly 6 bytes from the given reader and interpret them as a fixext4 type
56
/// with data attached.
57
///
58
/// According to the MessagePack specification, a fixext4 stores an integer and a byte array whose
59
/// length is 4 bytes. Its marker byte is `0xd6`.
60
///
61
/// Note, that this function copies a byte array from the reader to the output buffer, which is
62
/// unlikely if you want zero-copy functionality.
63
///
64
/// # Errors
65
///
66
/// This function will return `ValueReadError` on any I/O error while reading either the marker or
67
/// the data.
68
0
pub fn read_fixext4<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 4]), ValueReadError<R::Error>> {
69
0
    match read_marker(rd)? {
70
        Marker::FixExt4 => {
71
0
            let mut buf = [0; 4];
72
0
            read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
73
        },
74
0
        marker => Err(ValueReadError::TypeMismatch(marker)),
75
    }
76
0
}
77
78
/// Attempts to read exactly 10 bytes from the given reader and interpret them as a fixext8 type
79
/// with data attached.
80
///
81
/// According to the MessagePack specification, a fixext8 stores an integer and a byte array whose
82
/// length is 8 bytes. Its marker byte is `0xd7`.
83
///
84
/// Note, that this function copies a byte array from the reader to the output buffer, which is
85
/// unlikely if you want zero-copy functionality.
86
///
87
/// # Errors
88
///
89
/// This function will return `ValueReadError` on any I/O error while reading either the marker or
90
/// the data.
91
0
pub fn read_fixext8<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 8]), ValueReadError<R::Error>> {
92
0
    match read_marker(rd)? {
93
        Marker::FixExt8 => {
94
0
            let mut buf = [0; 8];
95
0
            read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
96
        },
97
0
        marker => Err(ValueReadError::TypeMismatch(marker)),
98
    }
99
0
}
100
101
/// Attempts to read exactly 18 bytes from the given reader and interpret them as a fixext16 type
102
/// with data attached.
103
///
104
/// According to the MessagePack specification, a fixext16 stores an integer and a byte array whose
105
/// length is 16 bytes. Its marker byte is `0xd8`.
106
///
107
/// Note, that this function copies a byte array from the reader to the output buffer, which is
108
/// unlikely if you want zero-copy functionality.
109
///
110
/// # Errors
111
///
112
/// This function will return `ValueReadError` on any I/O error while reading either the marker or
113
/// the data.
114
0
pub fn read_fixext16<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 16]), ValueReadError<R::Error>> {
115
0
    match read_marker(rd)? {
116
        Marker::FixExt16 => {
117
0
            let mut buf = [0; 16];
118
0
            read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
119
        },
120
0
        marker => Err(ValueReadError::TypeMismatch(marker)),
121
    }
122
0
}
123
124
0
fn read_fixext_data<R: RmpRead>(rd: &mut R, buf: &mut [u8]) -> Result<i8, ValueReadError<R::Error>> {
125
0
    let id = rd.read_data_i8()?;
126
0
    match rd.read_exact_buf(buf) {
127
0
        Ok(()) => Ok(id),
128
0
        Err(err) => Err(ValueReadError::InvalidDataRead(err)),
129
    }
130
0
}
131
132
/// Extension type meta information.
133
///
134
/// Extension represents a tuple of type information and a byte array where type information is an
135
/// integer whose meaning is defined by applications.
136
///
137
/// Applications can assign 0 to 127 to store application-specific type information.
138
///
139
/// # Note
140
///
141
/// MessagePack reserves -1 to -128 for future extension to add predefined types which will be
142
/// described in separated documents.
143
#[derive(Debug, PartialEq)]
144
pub struct ExtMeta {
145
    /// Type information.
146
    pub typeid: i8,
147
    /// Byte array size.
148
    pub size: u32,
149
}
150
151
0
pub fn read_ext_meta<R: RmpRead>(rd: &mut R) -> Result<ExtMeta, ValueReadError<R::Error>> {
152
0
    let size = match read_marker(rd)? {
153
0
        Marker::FixExt1 => 1,
154
0
        Marker::FixExt2 => 2,
155
0
        Marker::FixExt4 => 4,
156
0
        Marker::FixExt8 => 8,
157
0
        Marker::FixExt16 => 16,
158
0
        Marker::Ext8 => u32::from(rd.read_data_u8()?),
159
0
        Marker::Ext16 => u32::from(rd.read_data_u16()?),
160
0
        Marker::Ext32 => rd.read_data_u32()?,
161
0
        marker => return Err(ValueReadError::TypeMismatch(marker)),
162
    };
163
164
0
    let ty = rd.read_data_i8()?;
165
0
    let meta = ExtMeta { typeid: ty, size };
166
167
0
    Ok(meta)
168
0
}