libdd_profiling_protobuf/
location.rs1use crate::{Record, Value, WireType, NO_OPT_ZERO, OPT_ZERO};
5use std::io::{self, Write};
6
7#[repr(C)]
11#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
12#[cfg_attr(feature = "bolero", derive(bolero::generator::TypeGenerator))]
13pub struct Location {
14 pub id: Record<u64, 1, NO_OPT_ZERO>,
17 pub mapping_id: Record<u64, 2, OPT_ZERO>,
21 pub address: Record<u64, 3, OPT_ZERO>,
27 pub line: Record<Line, 4, OPT_ZERO>,
28}
29
30#[repr(C)]
32#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
33#[cfg_attr(feature = "bolero", derive(bolero::generator::TypeGenerator))]
34pub struct Line {
35 pub function_id: Record<u64, 1, OPT_ZERO>,
37 pub lineno: Record<i64, 2, OPT_ZERO>,
39}
40
41unsafe impl Value for Line {
44 const WIRE_TYPE: WireType = WireType::LengthDelimited;
45
46 fn proto_len(&self) -> u64 {
47 self.function_id.proto_len() + self.lineno.proto_len()
48 }
49
50 fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()> {
51 self.function_id.encode(writer)?;
52 self.lineno.encode(writer)
53 }
54}
55
56#[cfg(feature = "prost_impls")]
57impl From<Line> for crate::prost_impls::Line {
58 fn from(line: Line) -> Self {
59 #[allow(clippy::needless_update)]
62 Self {
63 function_id: line.function_id.value,
64 line: line.lineno.value,
65 ..Self::default()
66 }
67 }
68}
69
70unsafe impl Value for Location {
73 const WIRE_TYPE: WireType = WireType::LengthDelimited;
74
75 fn proto_len(&self) -> u64 {
76 self.id.proto_len()
77 + self.mapping_id.proto_len()
78 + self.address.proto_len()
79 + self.line.proto_len()
80 }
81
82 fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()> {
83 self.id.encode(writer)?;
84 self.mapping_id.encode(writer)?;
85 self.address.encode(writer)?;
86 self.line.encode(writer)
87 }
88}
89
90#[cfg(feature = "prost_impls")]
91impl From<&Location> for crate::prost_impls::Location {
92 fn from(location: &Location) -> Self {
93 Self {
94 id: location.id.value,
95 mapping_id: location.mapping_id.value,
96 address: location.address.value,
97 lines: if location.line == Default::default() {
98 Vec::new()
99 } else {
100 vec![crate::prost_impls::Line::from(location.line.value)]
101 },
102 is_folded: false,
103 }
104 }
105}
106
107#[cfg(feature = "prost_impls")]
108impl From<Location> for crate::prost_impls::Location {
109 fn from(location: Location) -> Self {
110 Self::from(&location)
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use crate::prost_impls;
118 use prost::Message;
119
120 #[track_caller]
121 fn test(location: &Location) {
122 let mut buffer = Vec::new();
123 let prost_location = prost_impls::Location::from(location);
124
125 location.encode(&mut buffer).unwrap();
126 let roundtrip = prost_impls::Location::decode(buffer.as_slice()).unwrap();
127 assert_eq!(prost_location, roundtrip);
128
129 let mut buffer2 = Vec::new();
132 prost_location.encode(&mut buffer2).unwrap();
133 let roundtrip2 = prost_impls::Location::decode(buffer2.as_slice()).unwrap();
134 assert_eq!(roundtrip, roundtrip2);
135 }
136
137 #[test]
138 fn basic() {
139 let location = Location {
140 id: Record::default(),
141 mapping_id: Record::default(),
142 address: Record::default(),
143 line: Record::from(Line {
144 function_id: Record::from(1),
145 lineno: Record::default(),
146 }),
147 };
148 test(&location);
149 }
150
151 #[test]
152 fn roundtrip() {
153 bolero::check!().with_type::<Location>().for_each(test);
154 }
155}