1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! PFCP message comparison functionality.
//!
//! This module provides tools for comparing PFCP messages with configurable options,
//! enabling use cases like testing, debugging, validation, and compliance auditing.
//!
//! # Overview
//!
//! The comparison system uses a builder pattern to provide flexible, type-safe
//! configuration of comparison behavior:
//!
//! ```rust,no_run
//! use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # fn example(msg1: &dyn Message, msg2: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//!
//! let result = MessageComparator::new(msg1, msg2)
//! .ignore_sequence()
//! .ignore_timestamps()
//! .compare()?;
//!
//! assert!(result.is_match());
//! # Ok(())
//! # }
//! ```
//!
//! # Comparison Levels
//!
//! ## Exact Comparison
//! Default behavior - all fields must match exactly:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # fn example(msg1: &dyn Message, msg2: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//! let result = MessageComparator::new(msg1, msg2)
//! .strict_mode()
//! .compare()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Semantic Comparison
//! Ignore transient fields, focus on functional equivalence:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # fn example(msg1: &dyn Message, msg2: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//! let result = MessageComparator::new(msg1, msg2)
//! .test_mode() // Ignores sequence, timestamps, etc.
//! .compare()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Focused Comparison
//! Compare only specific Information Elements:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # use rs_pfcp::ie::IeType;
//! # fn example(msg1: &dyn Message, msg2: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//! let result = MessageComparator::new(msg1, msg2)
//! .focus_on_ie_types(&[IeType::CreatePdr, IeType::CreateFar])
//! .compare()?;
//! # Ok(())
//! # }
//! ```
//!
//! # Diff Generation
//!
//! Generate detailed differences between messages:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # fn example(msg1: &dyn Message, msg2: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//! let diff = MessageComparator::new(msg1, msg2)
//! .with_detailed_diff()
//! .diff()?;
//!
//! println!("Differences found: {}", diff.len());
//! println!("{}", diff); // Human-readable output
//! # Ok(())
//! # }
//! ```
//!
//! # Use Cases
//!
//! ## Testing
//! Verify round-trip marshal/unmarshal operations:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::{Message, heartbeat_request::HeartbeatRequest};
//! # fn example(original: &HeartbeatRequest) -> Result<(), rs_pfcp::error::PfcpError> {
//! let bytes = original.marshal();
//! let parsed = HeartbeatRequest::unmarshal(&bytes)?;
//!
//! let result = MessageComparator::new(original, &parsed)
//! .test_mode()
//! .compare()?;
//!
//! assert!(result.is_match(), "Round-trip failed");
//! # Ok(())
//! # }
//! ```
//!
//! ## Debugging
//! Find differences between expected and actual messages:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # fn example(expected: &dyn Message, actual: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//! let diff = MessageComparator::new(expected, actual)
//! .include_payload_in_diff()
//! .diff()?;
//!
//! for difference in &diff.differences {
//! println!("Mismatch: {:?}", difference);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Validation
//! Ensure messages contain required IEs:
//! ```rust,no_run
//! # use rs_pfcp::comparison::MessageComparator;
//! # use rs_pfcp::message::Message;
//! # use rs_pfcp::comparison::OptionalIeMode;
//! # fn example(reference: &dyn Message, msg: &dyn Message) -> Result<(), rs_pfcp::error::PfcpError> {
//! let result = MessageComparator::new(reference, msg)
//! .optional_ie_mode(OptionalIeMode::RequireLeft)
//! .semantic_mode()
//! .matches()?;
//!
//! assert!(result, "Required IEs missing");
//! # Ok(())
//! # }
//! ```
pub use MessageComparator;
pub use ;
pub use ;
pub use ;
pub use ;