matrix_sdk_common/
debug.rs

1// Copyright 2023 The Matrix.org Foundation C.I.C.
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
15//! Helpers for creating `std::fmt::Debug` implementations.
16
17use std::fmt;
18
19use ruma::serde::Raw;
20
21pub trait DebugStructExt<'a, 'b> {
22    fn maybe_field<T: fmt::Debug>(
23        &mut self,
24        name: &str,
25        value: &Option<T>,
26    ) -> &mut fmt::DebugStruct<'a, 'b>;
27}
28
29impl<'a, 'b> DebugStructExt<'a, 'b> for fmt::DebugStruct<'a, 'b> {
30    fn maybe_field<T: fmt::Debug>(
31        &mut self,
32        name: &str,
33        value: &Option<T>,
34    ) -> &mut fmt::DebugStruct<'a, 'b> {
35        if let Some(value) = value {
36            self.field(name, value);
37        }
38
39        self
40    }
41}
42
43/// A wrapper around `Raw` that implements `Debug` in a way that only prints the
44/// event ID and event type.
45pub struct DebugRawEvent<'a, T>(pub &'a Raw<T>);
46
47#[cfg(not(tarpaulin_include))]
48impl<T> fmt::Debug for DebugRawEvent<'_, T> {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        f.debug_struct("RawEvent")
51            .field("event_id", &DebugStringField(self.0.get_field("event_id")))
52            .field("event_type", &DebugStringField(self.0.get_field("type")))
53            .finish_non_exhaustive()
54    }
55}
56
57/// A wrapper around `Raw` that implements `Debug` in a way that only prints the
58/// event type.
59pub struct DebugRawEventNoId<'a, T>(pub &'a Raw<T>);
60
61#[cfg(not(tarpaulin_include))]
62impl<T> fmt::Debug for DebugRawEventNoId<'_, T> {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        f.debug_struct("RawEvent")
65            .field("event_type", &DebugStringField(self.0.get_field("type")))
66            .finish_non_exhaustive()
67    }
68}
69
70struct DebugStringField(serde_json::Result<Option<String>>);
71
72#[cfg(not(tarpaulin_include))]
73impl fmt::Debug for DebugStringField {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        match &self.0 {
76            Ok(Some(id)) => id.fmt(f),
77            Ok(None) => f.write_str("Missing"),
78            Err(e) => f.debug_tuple("Invalid").field(&e).finish(),
79        }
80    }
81}