1use std::fmt;
8use std::fmt::{Display, Formatter, Write as _};
9
10use colored::Colorize as _;
11use mozjs::jsapi::JSProtoKey;
12
13use crate::format::descriptor::format_descriptor;
14use crate::format::object::write_remaining;
15use crate::format::prefix::write_prefix;
16use crate::format::{Config, NEWLINE, indent_str};
17use crate::{Array, Context};
18
19pub fn format_array<'cx>(cx: &'cx Context, cfg: Config, array: &'cx Array<'cx>) -> ArrayDisplay<'cx> {
21 ArrayDisplay { cx, array, cfg }
22}
23
24#[must_use]
25pub struct ArrayDisplay<'cx> {
26 cx: &'cx Context,
27 array: &'cx Array<'cx>,
28 cfg: Config,
29}
30
31impl Display for ArrayDisplay<'_> {
32 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
33 let colour = self.cfg.colours.array;
34
35 write_prefix(
36 f,
37 self.cx,
38 self.cfg,
39 self.array.as_object(),
40 "Array",
41 JSProtoKey::JSProto_Array,
42 )?;
43
44 if self.cfg.depth > 4 {
45 return "[Array]".color(colour).fmt(f);
46 }
47
48 let length = self.array.len(self.cx);
49 if length == 0 {
50 return "[]".color(colour).fmt(f);
51 }
52
53 "[".color(colour).fmt(f)?;
54 let (remaining, inner) = if self.cfg.multiline {
55 f.write_str(NEWLINE)?;
56 let shown = length.clamp(0, 100);
57
58 let inner = indent_str((self.cfg.indentation + self.cfg.depth + 1) as usize);
59
60 for index in 0..shown {
61 inner.fmt(f)?;
62 let desc = self.array.get_descriptor(self.cx, index)?.unwrap();
63 format_descriptor(self.cx, self.cfg, &desc, Some(self.array.as_object())).fmt(f)?;
64 ",".color(colour).fmt(f)?;
65 f.write_str(NEWLINE)?;
66 }
67
68 (length - shown, Some(inner))
69 } else {
70 f.write_char(' ')?;
71 let shown = length.clamp(0, 3);
72
73 for index in 0..shown {
74 let desc = self.array.get_descriptor(self.cx, index)?.unwrap();
75 format_descriptor(self.cx, self.cfg, &desc, Some(self.array.as_object())).fmt(f)?;
76
77 if index != shown - 1 {
78 ",".color(colour).fmt(f)?;
79 f.write_char(' ')?;
80 }
81 }
82
83 (length - shown, None)
84 };
85
86 write_remaining(f, remaining as usize, inner.as_deref(), colour)?;
87
88 if self.cfg.multiline {
89 indent_str((self.cfg.indentation + self.cfg.depth) as usize).fmt(f)?;
90 }
91
92 "]".color(colour).fmt(f)
93 }
94}