ion/format/
primitive.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 _;
11use itoa::Buffer;
12
13use crate::bigint::BigInt;
14use crate::conversions::FromValue as _;
15use crate::format::Config;
16use crate::format::string::format_string;
17use crate::format::symbol::format_symbol;
18use crate::{Context, Symbol, Value};
19
20/// Formats a primitive value using the given [configuration](Config).
21/// The supported types are `boolean`, `number`, `string`, `symbol`, `null` and `undefined`.
22pub fn format_primitive<'cx>(cx: &'cx Context, cfg: Config, value: &'cx Value<'cx>) -> PrimitiveDisplay<'cx> {
23	PrimitiveDisplay { cx, value, cfg }
24}
25
26#[must_use]
27pub struct PrimitiveDisplay<'cx> {
28	cx: &'cx Context,
29	value: &'cx Value<'cx>,
30	cfg: Config,
31}
32
33impl Display for PrimitiveDisplay<'_> {
34	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
35		let colours = self.cfg.colours;
36
37		let value = self.value.handle();
38		if value.is_boolean() {
39			value.to_boolean().to_string().color(colours.boolean).fmt(f)
40		} else if value.is_int32() {
41			let int = value.to_int32();
42			let mut buffer = Buffer::new();
43			buffer.format(int).color(colours.number).fmt(f)
44		} else if value.is_double() {
45			let number = value.to_double();
46
47			if number == f64::INFINITY {
48				"Infinity".color(colours.number).fmt(f)
49			} else if number == f64::NEG_INFINITY {
50				"-Infinity".color(colours.number).fmt(f)
51			} else {
52				number.to_string().color(colours.number).fmt(f)
53			}
54		} else if value.is_string() {
55			let str = crate::String::from_value(self.cx, self.value, true, ()).unwrap();
56			format_string(self.cx, self.cfg, &str).fmt(f)
57		} else if value.is_null() {
58			"null".color(colours.null).fmt(f)
59		} else if value.is_undefined() {
60			"undefined".color(colours.undefined).fmt(f)
61		} else if value.is_bigint() {
62			let bi = BigInt::from(self.cx.root(value.to_bigint()));
63			bi.to_string(self.cx, 10).unwrap().to_owned(self.cx)?.color(colours.bigint).fmt(f)?;
64			"n".color(colours.bigint).fmt(f)
65		} else if value.is_symbol() {
66			let symbol = Symbol::from(self.cx.root(value.to_symbol()));
67			format_symbol(self.cx, self.cfg, &symbol).fmt(f)
68		} else if value.is_magic() {
69			"<magic>".color(colours.boolean).fmt(f)
70		} else {
71			unreachable!("Expected Primitive")
72		}
73	}
74}