@@ -33,6 +33,14 @@ function print_toml_escaped(io::IO, s::AbstractString)
33
33
end
34
34
end
35
35
36
+ const MbyFunc = Union{Function, Nothing}
37
+ const TOMLValue = Union{AbstractVector, AbstractDict, Dates. DateTime, Dates. Time, Dates. Date, Bool, Integer, AbstractFloat, AbstractString}
38
+
39
+
40
+ # #######
41
+ # Keys #
42
+ # #######
43
+
36
44
function printkey (io:: IO , keys:: Vector{String} )
37
45
for (i, k) in enumerate (keys)
38
46
i != 1 && Base. print (io, " ." )
@@ -50,48 +58,74 @@ function printkey(io::IO, keys::Vector{String})
50
58
end
51
59
end
52
60
53
- const MbyFunc = Union{Function, Nothing}
54
- const TOMLValue = Union{AbstractVector, AbstractDict, Dates. DateTime, Dates. Time, Dates. Date, Bool, Integer, AbstractFloat, AbstractString}
55
- function printvalue (f:: MbyFunc , io:: IO , value:: AbstractVector ; sorted= false , by= identity)
61
+ function to_toml_value (f:: MbyFunc , value)
62
+ if f === nothing
63
+ error (" type `$(typeof (value)) ` is not a valid TOML type, pass a conversion function to `TOML.print`" )
64
+ end
65
+ toml_value = f (value)
66
+ if ! (toml_value isa TOMLValue)
67
+ error (" TOML syntax function for type `$(typeof (value)) ` did not return a valid TOML type but a `$(typeof (toml_value)) `" )
68
+ end
69
+ return toml_value
70
+ end
71
+
72
+ # #########
73
+ # Values #
74
+ # #########
75
+
76
+ # Fallback
77
+ function printvalue (f:: MbyFunc , io:: IO , value)
78
+ toml_value = to_toml_value (f, value)
79
+ @invokelatest printvalue (f, io, toml_value)
80
+ end
81
+
82
+ function printvalue (f:: MbyFunc , io:: IO , value:: AbstractVector )
56
83
Base. print (io, " [" )
57
84
for (i, x) in enumerate (value)
58
85
i != 1 && Base. print (io, " , " )
59
- if isa (x, AbstractDict)
60
- _print (f, io, x; sorted, by)
61
- else
62
- printvalue (f, io, x; sorted, by)
63
- end
86
+ printvalue (f, io, x)
64
87
end
65
88
Base. print (io, " ]" )
66
89
end
67
- printvalue (f:: MbyFunc , io:: IO , value:: AbstractDict ; sorted= false , by= identity) =
68
- _print (f, io, value; sorted, by)
69
- printvalue (f:: MbyFunc , io:: IO , value:: Dates.DateTime ; _... ) =
70
- Base. print (io, Dates. format (value, Dates. dateformat " YYYY-mm-dd\T HH:MM:SS.sss\Z " ))
71
- printvalue (f:: MbyFunc , io:: IO , value:: Dates.Time ; _... ) =
72
- Base. print (io, Dates. format (value, Dates. dateformat " HH:MM:SS.sss" ))
73
- printvalue (f:: MbyFunc , io:: IO , value:: Dates.Date ; _... ) =
74
- Base. print (io, Dates. format (value, Dates. dateformat " YYYY-mm-dd" ))
75
- printvalue (f:: MbyFunc , io:: IO , value:: Bool ; _... ) =
76
- Base. print (io, value ? " true" : " false" )
77
- printvalue (f:: MbyFunc , io:: IO , value:: Integer ; _... ) =
78
- Base. print (io, Int64 (value)) # TOML specifies 64-bit signed long range for integer
79
- printvalue (f:: MbyFunc , io:: IO , value:: AbstractFloat ; _... ) =
80
- Base. print (io, isnan (value) ? " nan" :
81
- ! (isfinite (value):: Bool ) ? string (value > 0 ? " +" : " -" , " inf" ) :
82
- Float64 (value)) # TOML specifies IEEE 754 binary64 for float
83
- function printvalue (f:: MbyFunc , io:: IO , value:: AbstractString ; _... )
84
- Base. print (io, " \" " )
85
- print_toml_escaped (io, value)
86
- Base. print (io, " \" " )
90
+
91
+ function printvalue (f:: MbyFunc , io:: IO , value:: TOMLValue )
92
+ value isa Dates. DateTime ? Base. print (io, Dates. format (value, Dates. dateformat " YYYY-mm-dd\T HH:MM:SS.sss\Z " )) :
93
+ value isa Dates. Time ? Base. print (io, Dates. format (value, Dates. dateformat " HH:MM:SS.sss" )) :
94
+ value isa Dates. Date ? Base. print (io, Dates. format (value, Dates. dateformat " YYYY-mm-dd" )) :
95
+ value isa Bool ? Base. print (io, value ? " true" : " false" ) :
96
+ value isa Integer ? Base. print (io, Int64 (value)) : # TOML specifies 64-bit signed long range for integer
97
+ value isa AbstractFloat ? Base. print (io, isnan (value) ? " nan" :
98
+ isinf (value) ? string (value > 0 ? " +" : " -" , " inf" ) :
99
+ Float64 (value)) : # TOML specifies IEEE 754 binary64 for float
100
+ value isa AbstractString ? (Base. print (io, " \" " );
101
+ print_toml_escaped (io, value);
102
+ Base. print (io, " \" " )) :
103
+ value isa AbstractDict ? print_inline_table (f, io, value) :
104
+ error (" internal error in TOML printing, unhandled value" )
105
+ end
106
+
107
+ function print_inline_table (f:: MbyFunc , io:: IO , value:: AbstractDict )
108
+ Base. print (io, " {" )
109
+ for (i, (k,v)) in enumerate (value)
110
+ i != 1 && Base. print (io, " , " )
111
+ printkey (io, [String (k)])
112
+ Base. print (io, " = " )
113
+ printvalue (f, io, v)
114
+ end
115
+ Base. print (io, " }" )
87
116
end
88
117
118
+
119
+ # #########
120
+ # Tables #
121
+ # #########
122
+
89
123
is_table (value) = isa (value, AbstractDict)
90
124
is_array_of_tables (value) = isa (value, AbstractArray) &&
91
125
length (value) > 0 && isa (value[1 ], AbstractDict)
92
126
is_tabular (value) = is_table (value) || is_array_of_tables (value)
93
127
94
- function _print (f:: MbyFunc , io:: IO , a:: AbstractDict ,
128
+ function print_table (f:: MbyFunc , io:: IO , a:: AbstractDict ,
95
129
ks:: Vector{String} = String[];
96
130
indent:: Int = 0 ,
97
131
first_block:: Bool = true ,
@@ -100,37 +134,30 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
100
134
)
101
135
akeys = keys (a)
102
136
if sorted
103
- akeys = sort! (collect (akeys); by)
137
+ akeys = sort! (collect (akeys); by= by )
104
138
end
105
139
106
140
# First print non-tabular entries
107
141
for key in akeys
108
142
value = a[key]
109
- is_tabular (value) && continue
110
143
if ! isa (value, TOMLValue)
111
- if f === nothing
112
- error (" type `$(typeof (value)) ` is not a valid TOML type, pass a conversion function to `TOML.print`" )
113
- end
114
- toml_value = f (value)
115
- if ! (toml_value isa TOMLValue)
116
- error (" TOML syntax function for type `$(typeof (value)) ` did not return a valid TOML type but a `$(typeof (toml_value)) `" )
117
- end
118
- value = toml_value
119
- end
120
- if is_tabular (value)
121
- _print (f, io, Dict (key => value); indent, first_block, sorted, by)
122
- else
123
- Base. print (io, ' ' ^ 4 max (0 ,indent- 1 ))
124
- printkey (io, [String (key)])
125
- Base. print (io, " = " ) # print separator
126
- printvalue (f, io, value; sorted, by)
127
- Base. print (io, " \n " ) # new line?
144
+ value = to_toml_value (f, value)
128
145
end
146
+ is_tabular (value) && continue
147
+
148
+ Base. print (io, ' ' ^ 4 max (0 ,indent- 1 ))
149
+ printkey (io, [String (key)])
150
+ Base. print (io, " = " ) # print separator
151
+ printvalue (f, io, value)
152
+ Base. print (io, " \n " ) # new line?
129
153
first_block = false
130
154
end
131
155
132
156
for key in akeys
133
157
value = a[key]
158
+ if ! isa (value, TOMLValue)
159
+ value = to_toml_value (f, value)
160
+ end
134
161
if is_table (value)
135
162
push! (ks, String (key))
136
163
header = isempty (value) || ! all (is_tabular (v) for v in values (value)):: Bool
@@ -144,7 +171,7 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
144
171
Base. print (io," ]\n " )
145
172
end
146
173
# Use runtime dispatch here since the type of value seems not to be enforced other than as AbstractDict
147
- @invokelatest _print (f, io, value, ks; indent = indent + header, first_block = header, sorted, by)
174
+ @invokelatest print_table (f, io, value, ks; indent = indent + header, first_block = header, sorted= sorted, by = by)
148
175
pop! (ks)
149
176
elseif is_array_of_tables (value)
150
177
# print array of tables
@@ -158,14 +185,19 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
158
185
Base. print (io," ]]\n " )
159
186
# TODO , nicer error here
160
187
! isa (v, AbstractDict) && error (" array should contain only tables" )
161
- @invokelatest _print (f, io, v, ks; indent = indent + 1 , sorted, by)
188
+ @invokelatest print_table (f, io, v, ks; indent = indent + 1 , sorted= sorted, by = by)
162
189
end
163
190
pop! (ks)
164
191
end
165
192
end
166
193
end
167
194
168
- print (f:: MbyFunc , io:: IO , a:: AbstractDict ; sorted:: Bool = false , by= identity) = _print (f, io, a; sorted, by)
169
- print (f:: MbyFunc , a:: AbstractDict ; sorted:: Bool = false , by= identity) = print (f, stdout , a; sorted, by)
170
- print (io:: IO , a:: AbstractDict ; sorted:: Bool = false , by= identity) = _print (nothing , io, a; sorted, by)
171
- print (a:: AbstractDict ; sorted:: Bool = false , by= identity) = print (nothing , stdout , a; sorted, by)
195
+
196
+ # ######
197
+ # API #
198
+ # ######
199
+
200
+ print (f:: MbyFunc , io:: IO , a:: AbstractDict ; sorted:: Bool = false , by= identity) = print_table (f, io, a; sorted= sorted, by= by)
201
+ print (f:: MbyFunc , a:: AbstractDict ; sorted:: Bool = false , by= identity) = print (f, stdout , a; sorted= sorted, by= by)
202
+ print (io:: IO , a:: AbstractDict ; sorted:: Bool = false , by= identity) = print_table (nothing , io, a; sorted= sorted, by= by)
203
+ print (a:: AbstractDict ; sorted:: Bool = false , by= identity) = print (nothing , stdout , a; sorted= sorted, by= by)
0 commit comments