Skip to content

Commit fed6636

Browse files
committed
[WIP] Rearrange folder structure.
1 parent b3b2852 commit fed6636

File tree

17 files changed

+913
-875
lines changed

17 files changed

+913
-875
lines changed

trace-utils/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ pub mod trace_utils;
1212
pub mod tracer_header_tags;
1313
pub mod tracer_payload;
1414

15-
pub mod span_v04;
15+
pub mod span;
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
pub mod error;
5+
pub mod number;
6+
pub mod span_link;
7+
pub mod string;
8+
use crate::msgpack_decoder::decode::error::DecodeError;
9+
use crate::msgpack_decoder::decode::number::read_number_bytes;
10+
use crate::msgpack_decoder::decode::string::{handle_null_marker, read_string_bytes};
11+
use rmp::{decode, decode::RmpRead, Marker};
12+
use std::{collections::HashMap, f64};
13+
use tinybytes::{Bytes, BytesString};
14+
15+
#[inline]
16+
pub fn read_metric_pair(buf: &mut Bytes) -> Result<(BytesString, f64), DecodeError> {
17+
let key = read_string_bytes(buf)?;
18+
let v = read_number_bytes(buf)?;
19+
20+
Ok((key, v))
21+
}
22+
#[inline]
23+
pub fn read_metrics(buf: &mut Bytes) -> Result<HashMap<BytesString, f64>, DecodeError> {
24+
if let Some(empty_map) = handle_null_marker(buf, HashMap::default) {
25+
return Ok(empty_map);
26+
}
27+
28+
let len = read_map_len(unsafe { buf.as_mut_slice() })?;
29+
30+
read_map(len, buf, read_metric_pair)
31+
}
32+
33+
#[inline]
34+
pub fn read_meta_struct(buf: &mut Bytes) -> Result<HashMap<BytesString, Vec<u8>>, DecodeError> {
35+
if let Some(empty_map) = handle_null_marker(buf, HashMap::default) {
36+
return Ok(empty_map);
37+
}
38+
39+
fn read_meta_struct_pair(buf: &mut Bytes) -> Result<(BytesString, Vec<u8>), DecodeError> {
40+
let key = read_string_bytes(buf)?;
41+
let array_len = decode::read_array_len(unsafe { buf.as_mut_slice() }).map_err(|_| {
42+
DecodeError::InvalidFormat("Unable to read array len for meta_struct".to_owned())
43+
})?;
44+
45+
let mut v = Vec::with_capacity(array_len as usize);
46+
47+
for _ in 0..array_len {
48+
let value = read_number_bytes(buf)?;
49+
v.push(value);
50+
}
51+
Ok((key, v))
52+
}
53+
54+
let len = read_map_len(unsafe { buf.as_mut_slice() })?;
55+
read_map(len, buf, read_meta_struct_pair)
56+
}
57+
58+
/// Reads a map from the buffer and returns it as a `HashMap`.
59+
///
60+
/// This function is generic over the key and value types of the map, and it uses a provided
61+
/// function to read key-value pairs from the buffer.
62+
///
63+
/// # Arguments
64+
///
65+
/// * `len` - The number of key-value pairs to read from the buffer.
66+
/// * `buf` - A reference to the Bytes containing the encoded map data.
67+
/// * `read_pair` - A function that reads a key-value pair from the buffer and returns it as a
68+
/// `Result<(K, V), DecodeError>`.
69+
///
70+
/// # Returns
71+
///
72+
/// * `Ok(HashMap<K, V>)` - A `HashMap` containing the decoded key-value pairs if successful.
73+
/// * `Err(DecodeError)` - An error if the decoding process fails.
74+
///
75+
/// # Errors
76+
///
77+
/// This function will return an error if:
78+
/// - The `read_pair` function returns an error while reading a key-value pair.
79+
///
80+
/// # Type Parameters
81+
///
82+
/// * `K` - The type of the keys in the map. Must implement `std::hash::Hash` and `Eq`.
83+
/// * `V` - The type of the values in the map.
84+
/// * `F` - The type of the function used to read key-value pairs from the buffer.
85+
#[inline]
86+
pub fn read_map<K, V, F>(
87+
len: usize,
88+
buf: &mut Bytes,
89+
read_pair: F,
90+
) -> Result<HashMap<K, V>, DecodeError>
91+
where
92+
K: std::hash::Hash + Eq,
93+
F: Fn(&mut Bytes) -> Result<(K, V), DecodeError>,
94+
{
95+
let mut map = HashMap::with_capacity(len);
96+
for _ in 0..len {
97+
let (k, v) = read_pair(buf)?;
98+
map.insert(k, v);
99+
}
100+
Ok(map)
101+
}
102+
103+
#[inline]
104+
pub fn read_map_len(buf: &mut &[u8]) -> Result<usize, DecodeError> {
105+
match decode::read_marker(buf)
106+
.map_err(|_| DecodeError::InvalidFormat("Unable to read marker for map".to_owned()))?
107+
{
108+
Marker::FixMap(len) => Ok(len as usize),
109+
Marker::Map16 => buf
110+
.read_data_u16()
111+
.map_err(|_| DecodeError::IOError)
112+
.map(|len| len as usize),
113+
Marker::Map32 => buf
114+
.read_data_u32()
115+
.map_err(|_| DecodeError::IOError)
116+
.map(|len| len as usize),
117+
_ => Err(DecodeError::InvalidType(
118+
"Unable to read map from buffer".to_owned(),
119+
)),
120+
}
121+
}

trace-utils/src/msgpack_decoder/v04/number.rs renamed to trace-utils/src/msgpack_decoder/decode/number.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use super::error::DecodeError;
4+
use crate::msgpack_decoder::decode::error::DecodeError;
55
use rmp::{decode::RmpRead, Marker};
66
use std::fmt;
77
use tinybytes::Bytes;

trace-utils/src/msgpack_decoder/v04/decoder/span_link.rs renamed to trace-utils/src/msgpack_decoder/decode/span_link.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use crate::msgpack_decoder::v04::decoder::{
4+
use crate::msgpack_decoder::decode::error::DecodeError;
5+
use crate::msgpack_decoder::decode::number::read_number_bytes;
6+
use crate::msgpack_decoder::decode::string::{
57
handle_null_marker, read_str_map_to_bytes_strings, read_string_bytes, read_string_ref,
68
};
7-
use crate::msgpack_decoder::v04::error::DecodeError;
8-
use crate::msgpack_decoder::v04::number::read_number_bytes;
9-
use crate::span_v04::SpanLink;
9+
use crate::span::v04::SpanLink;
1010
use rmp::Marker;
1111
use std::str::FromStr;
1212
use tinybytes::Bytes;
@@ -98,7 +98,7 @@ fn decode_span_link(buf: &mut Bytes) -> Result<SpanLink, DecodeError> {
9898
#[cfg(test)]
9999
mod tests {
100100
use super::SpanLinkKey;
101-
use crate::msgpack_decoder::v04::error::DecodeError;
101+
use crate::msgpack_decoder::decode::error::DecodeError;
102102
use std::str::FromStr;
103103

104104
#[test]
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::msgpack_decoder::decode::error::DecodeError;
5+
use rmp::decode;
6+
use rmp::decode::DecodeStringError;
7+
use std::collections::HashMap;
8+
use tinybytes::{Bytes, BytesString};
9+
10+
// https://docs.rs/rmp/latest/rmp/enum.Marker.html#variant.Null (0xc0 == 192)
11+
const NULL_MARKER: &u8 = &0xc0;
12+
13+
#[inline]
14+
pub fn read_string_ref_nomut(buf: &[u8]) -> Result<(&str, &[u8]), DecodeError> {
15+
decode::read_str_from_slice(buf).map_err(|e| match e {
16+
DecodeStringError::InvalidMarkerRead(e) => DecodeError::InvalidFormat(e.to_string()),
17+
DecodeStringError::InvalidDataRead(e) => DecodeError::InvalidConversion(e.to_string()),
18+
DecodeStringError::TypeMismatch(marker) => {
19+
DecodeError::InvalidType(format!("Type mismatch at marker {:?}", marker))
20+
}
21+
DecodeStringError::InvalidUtf8(_, e) => DecodeError::Utf8Error(e.to_string()),
22+
_ => DecodeError::IOError,
23+
})
24+
}
25+
26+
#[inline]
27+
pub fn read_string_ref<'a>(buf: &mut &'a [u8]) -> Result<&'a str, DecodeError> {
28+
read_string_ref_nomut(buf).map(|(str, newbuf)| {
29+
*buf = newbuf;
30+
str
31+
})
32+
}
33+
34+
#[inline]
35+
pub fn read_string_bytes(buf: &mut Bytes) -> Result<BytesString, DecodeError> {
36+
// Note: we need to pass a &'static lifetime here, otherwise it'll complain
37+
read_string_ref_nomut(unsafe { buf.as_mut_slice() }).map(|(str, newbuf)| {
38+
let string = BytesString::from_bytes_slice(buf, str);
39+
*unsafe { buf.as_mut_slice() } = newbuf;
40+
string
41+
})
42+
}
43+
44+
#[inline]
45+
pub fn read_nullable_string_bytes(buf: &mut Bytes) -> Result<BytesString, DecodeError> {
46+
if let Some(empty_string) = handle_null_marker(buf, BytesString::default) {
47+
Ok(empty_string)
48+
} else {
49+
read_string_bytes(buf)
50+
}
51+
}
52+
53+
#[inline]
54+
// Safety: read_string_ref checks utf8 validity, so we don't do it again when creating the
55+
// BytesStrings.
56+
pub fn read_str_map_to_bytes_strings(
57+
buf: &mut Bytes,
58+
) -> Result<HashMap<BytesString, BytesString>, DecodeError> {
59+
let len = decode::read_map_len(unsafe { buf.as_mut_slice() })
60+
.map_err(|_| DecodeError::InvalidFormat("Unable to get map len for str map".to_owned()))?;
61+
62+
let mut map = HashMap::with_capacity(len.try_into().expect("Unable to cast map len to usize"));
63+
for _ in 0..len {
64+
let key = read_string_bytes(buf)?;
65+
let value = read_string_bytes(buf)?;
66+
map.insert(key, value);
67+
}
68+
Ok(map)
69+
}
70+
71+
#[inline]
72+
pub fn read_nullable_str_map_to_bytes_strings(
73+
buf: &mut Bytes,
74+
) -> Result<HashMap<BytesString, BytesString>, DecodeError> {
75+
if let Some(empty_map) = handle_null_marker(buf, HashMap::default) {
76+
return Ok(empty_map);
77+
}
78+
79+
read_str_map_to_bytes_strings(buf)
80+
}
81+
82+
/// When you want to "peek" if the next value is a null marker, and only advance the buffer if it is
83+
/// null and return the default value. If it is not null, you can continue to decode as expected.
84+
#[inline]
85+
pub fn handle_null_marker<T, F>(buf: &mut Bytes, default: F) -> Option<T>
86+
where
87+
F: FnOnce() -> T,
88+
{
89+
let slice = unsafe { buf.as_mut_slice() };
90+
91+
if slice.first() == Some(NULL_MARKER) {
92+
*slice = &slice[1..];
93+
Some(default())
94+
} else {
95+
None
96+
}
97+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4+
pub mod decode;
45
pub mod v04;

0 commit comments

Comments
 (0)