]> WPIA git - cassiopeia.git/blob - src/log/format.cpp
180bb55eacf4e051f04884d0844fa04d5cf0575f
[cassiopeia.git] / src / log / format.cpp
1 #include "log/format.hpp"
2
3 #include <algorithm>
4 #include <cctype>
5 #include <tuple>
6
7 namespace logger {
8
9     namespace format {
10
11         inline namespace literals {
12
13             format_data operator"" _fmt( const char *it, std::size_t len ) {
14                 const auto end = it + len;
15                 auto retval = format_data {};
16
17                 if( it == end ) {
18                     return retval;
19                 }
20
21                 if( *it == '0' or !std::isalnum( *it ) ) {
22                     retval.fill = *it;
23                     ++it;
24                 }
25
26                 if( it == end ) {
27                     return retval;
28                 }
29
30                 if( std::isdigit( *it ) ) {
31                     const auto w_end = std::find_if_not( it, end,
32                     []( char c ) {
33                         return std::isdigit( c );
34                     } );
35                     retval.width = std::stoul( std::string{it, w_end} );
36                     it = w_end;
37                 }
38
39                 if( it == end ) {
40                     return retval;
41                 }
42
43                 switch( *it ) {
44                 case 's':
45                     break;
46
47                 case 'd':
48                     retval.base = 10;
49                     break;
50
51                 case 'x':
52                     retval.base = 16;
53                     break;
54
55                 case 'o':
56                     retval.base = 8;
57                     break;
58
59                 case 'l':
60                     retval.align_right = false;
61                     break;
62
63                 case 'r':
64                     retval.align_right = true;
65                     break;
66
67                 default:
68                     throw std::invalid_argument{"invalid format_data-string"};
69                 }
70
71                 ++it;
72
73                 if( it != end ) {
74                     throw std::invalid_argument{"invalid format_data-string"};
75                 }
76
77                 return retval;
78             }
79
80         } // inline namespace literals
81
82     } // namespace format
83
84     namespace conv {
85
86         std::string to_string( const format::formated_string& arg ) {
87             if( arg.value.size() >= arg.width ) {
88                 return arg.value;
89             }
90
91             auto str = std::string {};
92             str.reserve( arg.width );
93
94             if( arg.align_right ) {
95                 str.append( arg.width - arg.value.size(), arg.fill );
96                 str.append( arg.value );
97             } else {
98                 str.append( arg.value );
99                 str.append( arg.width - arg.value.size(), arg.fill );
100             }
101
102             return str;
103         }
104
105     } // namespace conv
106
107 } // namespace logger