bc_envelope/format/
envelope_summary.rs

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