micromegas_tracing/
string_id.rs

1//! StringId serializes the value of the pointer and the size of a UTF8 string.
2//! StaticStringRef should be prefered where wire compatibility with unreal is important.
3use std::sync::Arc;
4
5use micromegas_transit::{
6    InProcSerialize, Member, Reflect, UserDefinedType, Utf8StaticStringDependency,
7};
8
9#[derive(Debug)]
10pub struct StringId {
11    pub ptr: *const u8,
12    pub len: u32,
13}
14
15impl std::convert::From<&'static str> for StringId {
16    fn from(src: &'static str) -> Self {
17        Self {
18            len: src.len() as u32,
19            ptr: src.as_ptr(),
20        }
21    }
22}
23
24impl std::convert::From<&StringId> for Utf8StaticStringDependency {
25    fn from(src: &StringId) -> Self {
26        Self {
27            len: src.len,
28            ptr: src.ptr,
29        }
30    }
31}
32
33// TransitReflect derive macro does not support reference udts, only reference members
34impl Reflect for StringId {
35    fn reflect() -> UserDefinedType {
36        lazy_static::lazy_static! {
37            static ref TYPE_NAME: Arc<String> = Arc::new("StringId".into());
38            static ref ID: Arc<String> = Arc::new("id".into());
39        }
40        UserDefinedType {
41            name: TYPE_NAME.clone(),
42            size: std::mem::size_of::<Self>(),
43            members: vec![Member {
44                name: ID.clone(), // reference udt need a member named id that's 8 bytes
45                type_name: "usize".to_string(),
46                offset: memoffset::offset_of!(Self, ptr),
47                size: std::mem::size_of::<*const u8>(),
48                is_reference: true,
49            }],
50            is_reference: true,
51            secondary_udts: vec![],
52        }
53    }
54}
55
56impl InProcSerialize for StringId {}
57
58impl StringId {
59    pub fn id(&self) -> u64 {
60        self.ptr as u64
61    }
62}
63
64#[cfg(test)]
65mod test {
66    #[test]
67    fn test_string_id() {
68        use super::*;
69        let string_id = StringId::from("hello");
70        assert_eq!(string_id.len, 5);
71        assert_eq!(string_id.ptr, "hello".as_ptr());
72        assert_eq!(string_id.id(), "hello".as_ptr() as u64);
73
74        let mut buffer = vec![];
75        string_id.write_value(&mut buffer);
76        assert_eq!(buffer.len(), std::mem::size_of::<StringId>());
77
78        let string_id = unsafe { StringId::read_value(&buffer) };
79        assert_eq!(string_id.len, 5);
80        assert_eq!(string_id.ptr, "hello".as_ptr());
81    }
82}