mz_repr/explain/
dot.rs
1use crate::explain::*;
13
14pub trait DisplayDot<C = ()>
17where
18 Self: Sized,
19{
20 fn fmt_dot(&self, f: &mut fmt::Formatter<'_>, ctx: &mut C) -> fmt::Result;
21}
22
23impl<A, C> DisplayDot<C> for Box<A>
24where
25 A: DisplayDot<C>,
26{
27 fn fmt_dot(&self, f: &mut fmt::Formatter<'_>, ctx: &mut C) -> fmt::Result {
28 self.as_ref().fmt_dot(f, ctx)
29 }
30}
31
32impl<A, C> DisplayDot<C> for Option<A>
33where
34 A: DisplayDot<C>,
35{
36 fn fmt_dot(&self, f: &mut fmt::Formatter<'_>, ctx: &mut C) -> fmt::Result {
37 if let Some(val) = self {
38 val.fmt_dot(f, ctx)
39 } else {
40 fmt::Result::Ok(())
41 }
42 }
43}
44
45impl DisplayDot for UnsupportedFormat {
46 fn fmt_dot(&self, _f: &mut fmt::Formatter<'_>, _ctx: &mut ()) -> fmt::Result {
47 unreachable!()
48 }
49}
50
51pub fn dot_string<T: DisplayDot<()>>(t: &T) -> String {
57 struct DotString<'a, T>(&'a T);
58
59 impl<'a, T: DisplayDot> fmt::Display for DotString<'a, T> {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 self.0.fmt_dot(f, &mut ())
62 }
63 }
64
65 DotString::<'_>(t).to_string()
66}
67
68pub fn dot_string_at<'a, T: DisplayDot<C>, C, F: Fn() -> C>(t: &'a T, f: F) -> String {
75 struct DotStringAt<'a, T, C, F: Fn() -> C> {
76 t: &'a T,
77 f: F,
78 }
79
80 impl<T: DisplayDot<C>, C, F: Fn() -> C> DisplayDot<()> for DotStringAt<'_, T, C, F> {
81 fn fmt_dot(&self, f: &mut fmt::Formatter<'_>, _ctx: &mut ()) -> fmt::Result {
82 let mut ctx = (self.f)();
83 self.t.fmt_dot(f, &mut ctx)
84 }
85 }
86
87 dot_string(&DotStringAt { t, f })
88}