ion/format/
array.rs

1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 */
6
7use 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
19/// Formats an [JavaScript Array](Array) using the given [configuration](Config).
20pub 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}