bc_envelope/format/
envelope_summary.rs

1use dcbor::prelude::*;
2
3#[cfg(feature = "known_value")]
4use crate::extension::KnownValuesStore;
5use crate::{
6    Envelope, FormatContext, FormatContextOpt, Result,
7    base::envelope::EnvelopeCase, string_utils::StringUtils,
8};
9
10impl Envelope {
11    /// Returns a short summary of the envelope's content with a maximum length.
12    ///
13    /// # Arguments
14    /// * `max_length` - The maximum length of the summary
15    /// * `context` - The formatting context
16    pub fn summary(
17        &self,
18        max_length: usize,
19        context: &FormatContext,
20    ) -> String {
21        match self.case() {
22            EnvelopeCase::Node { .. } => "NODE".to_string(),
23            EnvelopeCase::Leaf { cbor, .. } => cbor
24                .envelope_summary(
25                    max_length,
26                    &FormatContextOpt::Custom(context),
27                )
28                .unwrap(),
29            EnvelopeCase::Wrapped { .. } => "WRAPPED".to_string(),
30            EnvelopeCase::Assertion(_) => "ASSERTION".to_string(),
31            EnvelopeCase::Elided(_) => "ELIDED".to_string(),
32            #[cfg(feature = "known_value")]
33            EnvelopeCase::KnownValue { value, .. } => {
34                let known_value = KnownValuesStore::known_value_for_raw_value(
35                    value.value(),
36                    Some(context.known_values()),
37                );
38                known_value.to_string().flanked_by("'", "'")
39            }
40            #[cfg(feature = "encrypt")]
41            EnvelopeCase::Encrypted(_) => "ENCRYPTED".to_string(),
42            #[cfg(feature = "compress")]
43            EnvelopeCase::Compressed(_) => "COMPRESSED".to_string(),
44        }
45    }
46}
47
48pub trait EnvelopeSummary {
49    fn envelope_summary(
50        &self,
51        max_length: usize,
52        context: &FormatContextOpt<'_>,
53    ) -> Result<String>;
54}
55
56impl EnvelopeSummary for CBOR {
57    fn envelope_summary(
58        &self,
59        max_length: usize,
60        context: &FormatContextOpt<'_>,
61    ) -> Result<String> {
62        match self.as_case() {
63            CBORCase::Unsigned(n) => Ok(n.to_string()),
64            CBORCase::Negative(n) => Ok((-1 - (*n as i128)).to_string()),
65            CBORCase::ByteString(data) => Ok(format!("Bytes({})", data.len())),
66            CBORCase::Text(string) => {
67                let string = if string.len() > max_length {
68                    format!(
69                        "{}…",
70                        string.chars().take(max_length).collect::<String>()
71                    )
72                } else {
73                    string.clone()
74                };
75                Ok(string.replace('\n', "\\n").flanked_by("\"", "\""))
76            }
77            CBORCase::Simple(v) => Ok(v.to_string()),
78
79            CBORCase::Array(_) => match context {
80                FormatContextOpt::None => Ok(self.diagnostic_opt(
81                    &DiagFormatOpts::default()
82                        .summarize(true)
83                        .tags(TagsStoreOpt::None),
84                )),
85                FormatContextOpt::Global => {
86                    crate::with_format_context!(|ctx: &FormatContext| {
87                        Ok(self.diagnostic_opt(
88                            &DiagFormatOpts::default()
89                                .summarize(true)
90                                .tags(TagsStoreOpt::Custom(ctx.tags())),
91                        ))
92                    })
93                }
94                FormatContextOpt::Custom(format_context) => Ok(self
95                    .diagnostic_opt(
96                        &DiagFormatOpts::default()
97                            .summarize(true)
98                            .tags(TagsStoreOpt::Custom(format_context.tags())),
99                    )),
100            },
101            CBORCase::Map(_) => match context {
102                FormatContextOpt::None => Ok(self.diagnostic_opt(
103                    &DiagFormatOpts::default()
104                        .summarize(true)
105                        .tags(TagsStoreOpt::None),
106                )),
107                FormatContextOpt::Global => {
108                    crate::with_format_context!(|ctx: &FormatContext| {
109                        Ok(self.diagnostic_opt(
110                            &DiagFormatOpts::default()
111                                .summarize(true)
112                                .tags(TagsStoreOpt::Custom(ctx.tags())),
113                        ))
114                    })
115                }
116                FormatContextOpt::Custom(format_context) => Ok(self
117                    .diagnostic_opt(
118                        &DiagFormatOpts::default()
119                            .summarize(true)
120                            .tags(TagsStoreOpt::Custom(format_context.tags())),
121                    )),
122            },
123            CBORCase::Tagged(_, _) => match context {
124                FormatContextOpt::None => Ok(self.diagnostic_opt(
125                    &DiagFormatOpts::default()
126                        .summarize(true)
127                        .tags(TagsStoreOpt::None),
128                )),
129                FormatContextOpt::Global => {
130                    crate::with_format_context!(|ctx: &FormatContext| {
131                        Ok(self.diagnostic_opt(
132                            &DiagFormatOpts::default()
133                                .summarize(true)
134                                .tags(TagsStoreOpt::Custom(ctx.tags())),
135                        ))
136                    })
137                }
138                FormatContextOpt::Custom(format_context) => Ok(self
139                    .diagnostic_opt(
140                        &DiagFormatOpts::default()
141                            .summarize(true)
142                            .tags(TagsStoreOpt::Custom(format_context.tags())),
143                    )),
144            },
145        }
146    }
147}