22
33import Dates
44
5+ import Base: @invokelatest
56import .. isvalid_barekey_char
67
78function printkey (io:: IO , keys:: Vector{String} )
@@ -20,46 +21,36 @@ function printkey(io::IO, keys::Vector{String})
2021end
2122
2223const MbyFunc = Union{Function, Nothing}
23- const TOMLValue = Union{AbstractVector, AbstractDict, Dates. DateTime, Dates. Time, Dates. Date, Bool, Integer, AbstractFloat, String }
24- function printvalue (f:: MbyFunc , io:: IO , value:: AbstractVector ; sorted= false )
24+ const TOMLValue = Union{AbstractVector, AbstractDict, Dates. DateTime, Dates. Time, Dates. Date, Bool, Integer, AbstractFloat, AbstractString }
25+ function printvalue (f:: MbyFunc , io:: IO , value:: AbstractVector ; sorted= false , by = identity )
2526 Base. print (io, " [" )
2627 for (i, x) in enumerate (value)
2728 i != 1 && Base. print (io, " , " )
2829 if isa (x, AbstractDict)
29- _print (f, io, x; sorted)
30+ _print (f, io, x; sorted, by )
3031 else
31- printvalue (f, io, x; sorted)
32+ printvalue (f, io, x; sorted, by )
3233 end
3334 end
3435 Base. print (io, " ]" )
3536end
36- function printvalue (f:: MbyFunc , io:: IO , value; sorted)
37- if f === nothing
38- error (" type `$(typeof (value)) ` is not a valid TOML type, pass a conversion function to `TOML.print`" )
39- end
40- toml_value = f (value)
41- if ! (toml_value isa TOMLValue)
42- error (" TOML syntax function for type `$(typeof (value)) ` did not return a valid TOML type but a `$(typeof (toml_value)) `" )
43- end
44- Base. invokelatest (printvalue, f, io, toml_value; sorted)
45- end
46- printvalue (f:: MbyFunc , io:: IO , value:: AbstractDict ; sorted) =
47- _print (f, io, value; sorted)
48- printvalue (f:: MbyFunc , io:: IO , value:: Dates.DateTime ; sorted) =
37+ printvalue (f:: MbyFunc , io:: IO , value:: AbstractDict ; sorted= false , by= identity) =
38+ _print (f, io, value; sorted, by)
39+ printvalue (f:: MbyFunc , io:: IO , value:: Dates.DateTime ; _... ) =
4940 Base. print (io, Dates. format (value, Dates. dateformat " YYYY-mm-dd\T HH:MM:SS.sss\Z " ))
50- printvalue (f:: MbyFunc , io:: IO , value:: Dates.Time ; sorted ) =
41+ printvalue (f:: MbyFunc , io:: IO , value:: Dates.Time ; _ ... ) =
5142 Base. print (io, Dates. format (value, Dates. dateformat " HH:MM:SS.sss" ))
52- printvalue (f:: MbyFunc , io:: IO , value:: Dates.Date ; sorted ) =
43+ printvalue (f:: MbyFunc , io:: IO , value:: Dates.Date ; _ ... ) =
5344 Base. print (io, Dates. format (value, Dates. dateformat " YYYY-mm-dd" ))
54- printvalue (f:: MbyFunc , io:: IO , value:: Bool ; sorted ) =
45+ printvalue (f:: MbyFunc , io:: IO , value:: Bool ; _ ... ) =
5546 Base. print (io, value ? " true" : " false" )
56- printvalue (f:: MbyFunc , io:: IO , value:: Integer ; sorted ) =
47+ printvalue (f:: MbyFunc , io:: IO , value:: Integer ; _ ... ) =
5748 Base. print (io, Int64 (value)) # TOML specifies 64-bit signed long range for integer
58- printvalue (f:: MbyFunc , io:: IO , value:: AbstractFloat ; sorted ) =
49+ printvalue (f:: MbyFunc , io:: IO , value:: AbstractFloat ; _ ... ) =
5950 Base. print (io, isnan (value) ? " nan" :
6051 isinf (value) ? string (value > 0 ? " +" : " -" , " inf" ) :
6152 Float64 (value)) # TOML specifies IEEE 754 binary64 for float
62- printvalue (f:: MbyFunc , io:: IO , value:: AbstractString ; sorted ) = Base. print (io, " \" " , escape_string (value), " \" " )
53+ printvalue (f:: MbyFunc , io:: IO , value:: AbstractString ; _ ... ) = Base. print (io, " \" " , escape_string (value), " \" " )
6354
6455is_table (value) = isa (value, AbstractDict)
6556is_array_of_tables (value) = isa (value, AbstractArray) &&
@@ -70,8 +61,8 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
7061 ks:: Vector{String} = String[];
7162 indent:: Int = 0 ,
7263 first_block:: Bool = true ,
73- sorted:: Bool ,
74- by:: Function ,
64+ sorted:: Bool = false ,
65+ by:: Function = identity ,
7566)
7667 akeys = keys (a)
7768 if sorted
@@ -82,11 +73,25 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
8273 for key in akeys
8374 value = a[key]
8475 is_tabular (value) && continue
85- Base. print (io, ' ' ^ 4 max (0 ,indent- 1 ))
86- printkey (io, [String (key)])
87- Base. print (io, " = " ) # print separator
88- printvalue (f, io, value; sorted)
89- Base. print (io, " \n " ) # new line?
76+ if ! isa (value, TOMLValue)
77+ if f === nothing
78+ error (" type `$(typeof (value)) ` is not a valid TOML type, pass a conversion function to `TOML.print`" )
79+ end
80+ toml_value = f (value)
81+ if ! (toml_value isa TOMLValue)
82+ error (" TOML syntax function for type `$(typeof (value)) ` did not return a valid TOML type but a `$(typeof (toml_value)) `" )
83+ end
84+ value = toml_value
85+ end
86+ if is_tabular (value)
87+ _print (f, io, Dict (key => value); indent, first_block, sorted, by)
88+ else
89+ Base. print (io, ' ' ^ 4 max (0 ,indent- 1 ))
90+ printkey (io, [String (key)])
91+ Base. print (io, " = " ) # print separator
92+ printvalue (f, io, value; sorted, by)
93+ Base. print (io, " \n " ) # new line?
94+ end
9095 first_block = false
9196 end
9297
@@ -105,7 +110,7 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
105110 Base. print (io," ]\n " )
106111 end
107112 # Use runtime dispatch here since the type of value seems not to be enforced other than as AbstractDict
108- Base . invokelatest (_print, f, io, value, ks; indent = indent + header, first_block = header, sorted, by)
113+ @ invokelatest _print ( f, io, value, ks; indent = indent + header, first_block = header, sorted, by)
109114 pop! (ks)
110115 elseif is_array_of_tables (value)
111116 # print array of tables
@@ -119,7 +124,7 @@ function _print(f::MbyFunc, io::IO, a::AbstractDict,
119124 Base. print (io," ]]\n " )
120125 # TODO , nicer error here
121126 ! isa (v, AbstractDict) && error (" array should contain only tables" )
122- Base . invokelatest (_print, f, io, v, ks; indent = indent + 1 , sorted, by)
127+ @ invokelatest _print ( f, io, v, ks; indent = indent + 1 , sorted, by)
123128 end
124129 pop! (ks)
125130 end
0 commit comments