ion/format/
symbol.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};
9
10use colored::Colorize as _;
11
12use crate::format::Config;
13use crate::symbol::SymbolCode;
14use crate::{Context, Symbol};
15
16/// Formats a [Symbol] as a [String] with the given [configuration](Config).
17///
18/// ### Format
19/// Well-Known Symbols such as `@@iterator` are formatted as `Symbol.iterator`.
20/// Unique Symbols are formatted as `Symbol(<#symbol>)`.
21/// Registry Symbols are formatted as `Symbol.for(<#symbol>)`.
22/// Private Name Symbols are formatted as `#private`.
23pub fn format_symbol<'cx>(cx: &'cx Context, cfg: Config, symbol: &'cx Symbol<'cx>) -> SymbolDisplay<'cx> {
24	SymbolDisplay { cx, symbol, cfg }
25}
26
27#[must_use]
28pub struct SymbolDisplay<'cx> {
29	cx: &'cx Context,
30	symbol: &'cx Symbol<'cx>,
31	cfg: Config,
32}
33
34impl Display for SymbolDisplay<'_> {
35	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
36		let colour = self.cfg.colours.symbol;
37		let code = self.symbol.code();
38
39		match code {
40			SymbolCode::WellKnown(code) => {
41				"Symbol.".color(colour).fmt(f)?;
42				code.identifier().color(colour).fmt(f)
43			}
44			code => {
45				let description = self
46					.symbol
47					.description(self.cx)
48					.expect("Expected Description on Non-Well-Known Symbol")
49					.color(colour);
50
51				match code {
52					SymbolCode::PrivateNameSymbol => return description.fmt(f),
53					SymbolCode::InSymbolRegistry => "Symbol.for(".color(colour).fmt(f)?,
54					SymbolCode::UniqueSymbol => "Symbol(".color(colour).fmt(f)?,
55					_ => unreachable!(),
56				}
57
58				description.fmt(f)?;
59				")".color(colour).fmt(f)
60			}
61		}
62	}
63}