ion/format/
typedarray.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 itoa::Buffer;
12
13use crate::format::{Config, NEWLINE, indent_str};
14use crate::typedarray::{ArrayBuffer, TypedArray, TypedArrayElement};
15
16pub fn format_array_buffer<'cx>(cfg: Config, buffer: &'cx ArrayBuffer<'cx>) -> ArrayBufferDisplay<'cx> {
17	ArrayBufferDisplay { buffer, cfg }
18}
19
20#[must_use]
21pub struct ArrayBufferDisplay<'cx> {
22	buffer: &'cx ArrayBuffer<'cx>,
23	cfg: Config,
24}
25
26impl Display for ArrayBufferDisplay<'_> {
27	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
28		let colour = self.cfg.colours.object;
29		"ArrayBuffer {".color(colour).fmt(f)?;
30
31		let vec;
32		let bytes = if self.buffer.is_shared() {
33			vec = unsafe { self.buffer.as_slice().to_vec() };
34			&vec
35		} else {
36			unsafe { self.buffer.as_slice() }
37		};
38
39		let indent = indent_str((self.cfg.indentation + self.cfg.depth + 1) as usize);
40		if bytes.len() < 8 {
41			f.write_char(' ')?;
42		} else {
43			f.write_str(NEWLINE)?;
44			indent.fmt(f)?;
45		}
46
47		write!(
48			f,
49			"{}{} ",
50			"[Uint8Contents]".color(self.cfg.colours.symbol),
51			":".color(colour)
52		)?;
53		f.write_char('<')?;
54
55		for (i, byte) in bytes.iter().enumerate() {
56			write!(f, "{byte:02x}")?;
57
58			if i != bytes.len() - 1 {
59				f.write_char(' ')?;
60			}
61		}
62
63		f.write_char('>')?;
64		",".color(colour).fmt(f)?;
65		if bytes.len() < 8 {
66			f.write_char(' ')?;
67		} else {
68			f.write_str(NEWLINE)?;
69			indent.fmt(f)?;
70		}
71
72		write!(f, "byteLength: {}", bytes.len())?;
73		if bytes.len() < 8 {
74			f.write_char(' ')?;
75		} else {
76			f.write_str(NEWLINE)?;
77		}
78
79		"}".color(colour).fmt(f)?;
80
81		Ok(())
82	}
83}
84
85pub fn format_typed_array<'cx, T: TypedArrayElement>(
86	cfg: Config, array: &'cx TypedArray<'cx, T>,
87) -> TypedArrayDisplay<'cx, T>
88where
89	T::Element: Display + Copy,
90{
91	TypedArrayDisplay { array, cfg }
92}
93
94pub struct TypedArrayDisplay<'cx, T: TypedArrayElement>
95where
96	T::Element: Display + Copy,
97{
98	array: &'cx TypedArray<'cx, T>,
99	cfg: Config,
100}
101
102impl<T: TypedArrayElement> Display for TypedArrayDisplay<'_, T>
103where
104	T::Element: Display + Copy,
105{
106	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
107		let colour = self.cfg.colours.object;
108
109		let vec;
110		let elements = if self.array.is_shared() {
111			vec = unsafe { self.array.as_slice().to_vec() };
112			&vec
113		} else {
114			unsafe { self.array.as_slice() }
115		};
116
117		let mut buffer = Buffer::new();
118		write!(
119			f,
120			"{}{}{}{}",
121			T::NAME.color(colour),
122			"(".color(colour),
123			buffer.format(elements.len()).color(self.cfg.colours.number),
124			") [".color(colour)
125		)?;
126
127		if elements.is_empty() {
128			return "]".color(colour).fmt(f);
129		}
130
131		let indent = indent_str((self.cfg.indentation + self.cfg.depth + 1) as usize);
132		f.write_str(NEWLINE)?;
133		indent.fmt(f)?;
134
135		for (i, element) in elements.iter().enumerate() {
136			element.to_string().color(self.cfg.colours.number).fmt(f)?;
137			",".color(colour).fmt(f)?;
138
139			if i != elements.len() - 1 {
140				f.write_char(' ')?;
141				if (i + 1) % 16 == 0 {
142					f.write_str(NEWLINE)?;
143					indent.fmt(f)?;
144				}
145			}
146		}
147
148		f.write_str(NEWLINE)?;
149		"]".color(colour).fmt(f)?;
150
151		Ok(())
152	}
153}