1use std::fmt;
8use std::fmt::{Display, Formatter, Write as _};
9
10use colored::Colorize as _;
11
12use crate::format::object::format_object;
13use crate::format::primitive::format_primitive;
14use crate::format::{Config, format_value};
15use crate::{Context, Function, Object, PropertyDescriptor};
16
17pub fn format_descriptor<'cx>(
19 cx: &'cx Context, cfg: Config, desc: &'cx PropertyDescriptor<'cx>, object: Option<&'cx Object<'cx>>,
20) -> DescriptorDisplay<'cx> {
21 DescriptorDisplay { cx, cfg, desc, object }
22}
23
24#[must_use]
25pub struct DescriptorDisplay<'cx> {
26 cx: &'cx Context,
27 cfg: Config,
28 desc: &'cx PropertyDescriptor<'cx>,
29 object: Option<&'cx Object<'cx>>,
30}
31
32impl Display for DescriptorDisplay<'_> {
33 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
34 let color = self.cfg.colours.function;
35
36 if let Some(getter) = self.desc.getter(self.cx) {
37 "[Getter".color(color).fmt(f)?;
38 if self.desc.setter(self.cx).is_some() {
39 "/Setter".color(color).fmt(f)?;
40 }
41
42 if let Some(object) = self.object {
43 format_getter(f, self.cx, &getter, object, self.cfg)
44 } else {
45 "]".color(color).fmt(f)
46 }
47 } else if self.desc.setter(self.cx).is_some() {
48 "[Setter]".color(color).fmt(f)
49 } else {
50 match self.desc.value(self.cx) {
51 Some(value) => format_value(self.cx, self.cfg.depth(self.cfg.depth + 1).quoted(true), &value).fmt(f),
52 None => f.write_str("<empty descriptor>"),
53 }
54 }
55 }
56}
57
58fn format_getter(f: &mut Formatter<'_>, cx: &Context, getter: &Function, object: &Object, cfg: Config) -> fmt::Result {
59 let color = cfg.colours.function;
60
61 let value = match getter.call(cx, object, &[]) {
62 Ok(value) => value,
63 Err(report) => {
64 f.write_str(" <Inspection threw ")?;
65 match report {
66 Some(mut report) => {
67 report.stack = None;
68 f.write_char('(')?;
69 report.format(cx).fmt(f)?;
70 f.write_char(')')?;
71 }
72 None => f.write_str("unknown error")?,
73 }
74 f.write_char('>')?;
75 return "]".color(color).fmt(f);
76 }
77 };
78
79 if value.handle().is_object() {
80 "] ".color(color).fmt(f)?;
81 format_object(cx, cfg.depth(cfg.depth + 1).quoted(true), value.to_object(cx)).fmt(f)
82 } else {
83 ": ".color(color).fmt(f)?;
84 format_primitive(cx, cfg.quoted(true), &value).fmt(f)?;
85 "]".color(color).fmt(f)
86 }
87}