mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Add fmt.User_Formatter
This commit is contained in:
+48
-1
@@ -10,7 +10,6 @@ import "core:strings"
|
|||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
import "intrinsics"
|
import "intrinsics"
|
||||||
|
|
||||||
|
|
||||||
@private
|
@private
|
||||||
DEFAULT_BUFFER_SIZE :: 1<<12;
|
DEFAULT_BUFFER_SIZE :: 1<<12;
|
||||||
|
|
||||||
@@ -35,6 +34,34 @@ Info :: struct {
|
|||||||
record_level: int,
|
record_level: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom formatter signature. It returns true if the formatting was successful and false when it could not be done
|
||||||
|
User_Formatter :: #type proc(fi: ^Info, arg: any, verb: rune) -> bool;
|
||||||
|
|
||||||
|
Register_User_Formatter_Error :: enum {
|
||||||
|
None,
|
||||||
|
No_User_Formatter,
|
||||||
|
Formatter_Previously_Found,
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(bill): This is a pointer to prevent accidental additions
|
||||||
|
// it is prefixed with `_` rather than marked with a private attribute so that users can access it if necessary
|
||||||
|
_user_formatters: ^map[typeid]User_Formatter;
|
||||||
|
|
||||||
|
set_user_formatters :: proc(m: ^map[typeid]User_Formatter) {
|
||||||
|
_user_formatters = m;
|
||||||
|
}
|
||||||
|
register_user_formatter :: proc(id: typeid, formatter: User_Formatter) -> Register_User_Formatter_Error {
|
||||||
|
if _user_formatters == nil {
|
||||||
|
return .No_User_Formatter;
|
||||||
|
}
|
||||||
|
if prev, found := _user_formatters[id]; found && prev != nil {
|
||||||
|
return .Formatter_Previously_Found;
|
||||||
|
}
|
||||||
|
_user_formatters[id] = formatter;
|
||||||
|
return .None;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fprint :: proc(fd: os.Handle, args: ..any) -> int {
|
fprint :: proc(fd: os.Handle, args: ..any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := strings.builder_from_slice(data[:]);
|
buf := strings.builder_from_slice(data[:]);
|
||||||
@@ -1189,6 +1216,16 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _user_formatters != nil {
|
||||||
|
formatter := _user_formatters[v.id];
|
||||||
|
if formatter != nil {
|
||||||
|
if ok := formatter(fi, v, verb); !ok {
|
||||||
|
fmt_bad_verb(fi, verb);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type_info := type_info_of(v.id);
|
type_info := type_info_of(v.id);
|
||||||
switch info in type_info.variant {
|
switch info in type_info.variant {
|
||||||
case runtime.Type_Info_Any: // Ignore
|
case runtime.Type_Info_Any: // Ignore
|
||||||
@@ -1795,6 +1832,16 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _user_formatters != nil {
|
||||||
|
formatter := _user_formatters[arg.id];
|
||||||
|
if formatter != nil {
|
||||||
|
if ok := formatter(fi, arg, verb); !ok {
|
||||||
|
fmt_bad_verb(fi, verb);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
custom_types: switch a in arg {
|
custom_types: switch a in arg {
|
||||||
case runtime.Source_Code_Location:
|
case runtime.Source_Code_Location:
|
||||||
|
|||||||
Reference in New Issue
Block a user