flogging_macros/src/format.rs

Lines

100.00 %

Functions

100.00 %

Regions

100.00 %

LineCountSource
1
//
2
// File Name:    fmt_log.rs
3
// Project Name: flogging
4
//
5
// Copyright (C) 2025 Bradley Willcott
6
//
7
// SPDX-License-Identifier: GPL-3.0-or-later
8
//
9
// This library (crate) is free software: you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation, either version 3 of the License, or
12
// (at your option) any later version.
13
//
14
// This library (crate) is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
//
19
// You should have received a copy of the GNU General Public License
20
// along with this library (crate).  If not, see <https://www.gnu.org/licenses/>.
21
//
22
23
//!
24
//! # format Macro Impl
25
//!
26
//! Format the Log function call (Rust code)
27
//!
28
29
use dyn_fmt::AsStrFormatExt;
30
use proc_macro::TokenStream;
31
use regex::RegexBuilder;
32
3333
pub(crate) fn format_impl(fmt_str: &str, msg: TokenStream) -> TokenStream {
34
    // println!("msg: {}", &msg);
35
3632
    let fmt = "let __fmt = format!({});\n".format(&[
3733
        match process_msg(msg){
3832
            Some(r_msg) => r_msg,
391
            None => return TokenStream::new(),
40
        }
41
        ]);
42
4332
    let mut buf = String::new();
4432
    buf.push_str(&fmt);
4532
    buf.push_str(fmt_str);
46
47
    // let rtn = buf.parse().unwrap_or_default();
48
    // println!("{rtn}");
49
    // rtn
5032
    buf.parse().unwrap_or_default()
5133
}
52
///
53
/// Check for `object` only `msg`.
54
///
55
/// If found, provide default format string.
56
///
5733
fn process_msg(msg: TokenStream) -> Option<String> {
5833
    let text = msg.to_string();
59
6033
    if text.is_empty() {
611
        return None;
6232
    }
63
6428
    if text.starts_with('\"') && text.ends_with('\"') {
6519
        return Some(text);
6613
    }
67
6813
    let regex_str = "(?<fmt>\".*\\{.*\\}.*\")(,[\\s]*(?<attrs>.*)*)";
69
7013
    let re = RegexBuilder::new(regex_str)
7113
        .dot_matches_new_line(true)
7213
        .build()
7313
        .unwrap();
74
7513
    if re.is_match(&text) {
769
        Some(text)
77
    } else {
784
        let count = text.split(',').count();
79
804
        let mut buf = String::new();
81
823
        if count == 1 {
833
            buf.push_str("\"{}\", ");
843
        } else {
851
            buf.push_str("\"{}");
86
872
            for _i in 1..count {
882
                buf.push_str(", {}");
892
            }
90
911
            buf.push_str("\", ");
92
        }
93
944
        buf.push_str(&text);
95
964
        Some(buf)
97
    }
9833
}