hexga_core/
format.rs

1use super::*;
2
3pub use std::fmt::{format,Formatter,Debug,Display};
4pub type FmtResult = std::fmt::Result;
5
6pub trait ToDebug
7{
8    fn to_debug(&self) -> String;
9}
10impl<T> ToDebug for T where T: std::fmt::Debug
11{
12    #[inline(always)]
13    fn to_debug(&self) -> String {
14        format!("{:?}", self)
15    }
16}
17
18
19pub trait DebugExtension
20{
21    fn field_if<T : Debug>(&mut self, name: &str, value: &T, pred : impl FnOnce(&T) -> bool) -> &mut Self;
22    fn field_if_not_default<T : Debug + Default + PartialEq>(&mut self, name: &str, value: &T) -> &mut Self { self.field_if(name, value, |v| v.is_not_default()) }
23
24    fn field<T : Debug>(&mut self, name: &str, value: &T) -> &mut Self;
25
26    fn field_if_false(&mut self, name: &str, value: bool) -> &mut Self { if !value { self.field(name, &value); } self }
27    fn field_if_true(&mut self, name: &str, value: bool) -> &mut Self { if value { self.field(name, &value); } self }
28
29    fn field_bool(&mut self, value : bool, name_true : &str, name_false : &str) -> &mut Self;
30}
31
32impl<'a, 'b: 'a> DebugExtension for std::fmt::DebugStruct<'a, 'b>
33{
34    fn field_if<T : Debug>(&mut self, name: &str, value: &T, pred : impl FnOnce(&T) -> bool) -> &mut Self
35    {
36        if pred(value)
37        {
38            self.field(name, value);
39        }
40        self
41    }
42
43    fn field<T : Debug>(&mut self, name: &str, value: &T) -> &mut Self {
44        self.field(name, value)
45    }
46
47    fn field_bool(&mut self, value : bool, name_true : &str, name_false : &str) -> &mut Self {
48        self.field(if value { name_true } else { name_false }, &())
49    }
50}
51
52pub struct FmtOptional<'a, T>
53{
54    value : Option<&'a T>,
55    separator : &'static str,
56}
57impl<'a, T> FmtOptional<'a, T>
58{
59    pub fn new(value: Option<&'a T>) -> Self { Self { value, separator: " " }}
60    pub fn with_separator(mut self, separator : &'static str) -> Self { self.separator = separator; self }
61}
62
63
64hexga_map_on::map_on_std_fmt!(
65    ($trait_name:ident) =>
66    {
67        impl<'a, T> std::fmt::$trait_name for FmtOptional<'a, T> where T: std::fmt::$trait_name
68        {
69            fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult
70            {
71                match self.value
72                {
73                    Some(v) =>
74                    {
75                        v.fmt(f)?;
76                        f.write_str(self.separator)
77                    },
78                    None => Ok(()),
79                }
80            }
81        }
82    }
83);
84
85/*
86pub trait FmtOptionalDefault : Sized
87{
88    /// Formats the value with a space separator after it only if it is not the default.
89    fn fmt_if_not_defaut(&self) -> FmtOptional<'_, Self> where Self: Default + PartialEq
90    {
91        FmtOptional::new(if self.is_default() { None } else { Some(self) })
92    }
93}
94impl<T> FmtOptionalDefault for T where T: Sized {}
95*/