Skip to main content

rocketmq_protocol/trace/
trace_type.rs

1// Copyright 2026 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18pub enum TraceType {
19    #[default]
20    Pub,
21    SubBefore,
22    SubAfter,
23    EndTransaction,
24    Recall,
25}
26
27impl TraceType {
28    pub fn parse(value: &str) -> Option<Self> {
29        match value {
30            "Pub" => Some(Self::Pub),
31            "SubBefore" => Some(Self::SubBefore),
32            "SubAfter" => Some(Self::SubAfter),
33            "EndTransaction" => Some(Self::EndTransaction),
34            "Recall" => Some(Self::Recall),
35            _ => None,
36        }
37    }
38}
39
40impl Display for TraceType {
41    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        formatter.write_str(match self {
43            Self::Pub => "Pub",
44            Self::SubBefore => "SubBefore",
45            Self::SubAfter => "SubAfter",
46            Self::EndTransaction => "EndTransaction",
47            Self::Recall => "Recall",
48        })
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    const WIRE_NAMES: [(&str, TraceType); 5] = [
57        ("Pub", TraceType::Pub),
58        ("SubBefore", TraceType::SubBefore),
59        ("SubAfter", TraceType::SubAfter),
60        ("EndTransaction", TraceType::EndTransaction),
61        ("Recall", TraceType::Recall),
62    ];
63
64    #[test]
65    fn parse_maps_each_wire_name_to_its_variant() {
66        for (name, expected) in WIRE_NAMES {
67            assert_eq!(TraceType::parse(name), Some(expected), "parse({name:?})");
68        }
69    }
70
71    #[test]
72    fn parse_rejects_unknown_empty_and_case_variants() {
73        for input in [
74            "",
75            "Unknown",
76            "pub",
77            "PUB",
78            "subBefore",
79            "SUBAFTER",
80            " Pub",
81            "Pub ",
82            "Pub\u{1}",
83        ] {
84            assert_eq!(TraceType::parse(input), None, "parse({input:?}) should be None");
85        }
86    }
87
88    #[test]
89    fn display_prints_exact_wire_name_and_round_trips_through_parse() {
90        for (name, variant) in WIRE_NAMES {
91            let rendered = variant.to_string();
92            assert_eq!(rendered, name, "{variant:?} wire name");
93            assert_eq!(TraceType::parse(&rendered), Some(variant), "{variant:?} round trip");
94        }
95    }
96
97    #[test]
98    fn default_is_pub() {
99        assert_eq!(TraceType::default(), TraceType::Pub);
100    }
101}