Browse Source

Merge pull request #3751 from Kelimion/custom_formatter

Add example of a custom formatter.
Jeroen van Rijn 1 year ago
parent
commit
20c17ba6f9
1 changed files with 57 additions and 0 deletions
  1. 57 0
      core/fmt/example.odin

+ 57 - 0
core/fmt/example.odin

@@ -0,0 +1,57 @@
+//+build ignore
+package custom_formatter_example
+import "core:fmt"
+import "core:io"
+
+SomeType :: struct {
+	value: int,
+}
+
+My_Custom_Base_Type :: distinct u32
+
+main :: proc() {
+ 	// Ensure the fmt._user_formatters map is initialized
+	fmt.set_user_formatters(new(map[typeid]fmt.User_Formatter))
+
+	// Register custom formatters for my favorite types
+	err := fmt.register_user_formatter(type_info_of(SomeType).id, SomeType_Formatter)
+ 	assert(err == .None)
+	err  = fmt.register_user_formatter(type_info_of(My_Custom_Base_Type).id, My_Custom_Base_Formatter)
+ 	assert(err == .None)
+
+	// Use the custom formatters.
+	fmt.printfln("SomeType{{42}}: '%v'", SomeType{42})
+	fmt.printfln("My_Custom_Base_Type(0xdeadbeef): '%v'", My_Custom_Base_Type(0xdeadbeef))
+}
+
+SomeType_Formatter :: proc(fi: ^fmt.Info, arg: any, verb: rune) -> bool {
+	m := cast(^SomeType)arg.data
+	switch verb {
+	case 'v', 'd': // We handle `%v` and `%d`
+		fmt.fmt_int(fi, u64(m.value), true, 8 * size_of(SomeType), verb)
+	case:
+		return false
+	}
+	return true
+}
+
+My_Custom_Base_Formatter :: proc(fi: ^fmt.Info, arg: any, verb: rune) -> bool {
+	m := cast(^My_Custom_Base_Type)arg.data
+	switch verb {
+	case 'v', 'b':
+		value := u64(m^)
+		for value > 0 {
+			if value & 1 == 1 {
+				io.write_string(fi.writer, "Hellope!", &fi.n)
+			} else {
+				io.write_string(fi.writer, "Hellope?", &fi.n)
+			}
+			value >>= 1
+		}
+
+	case:
+		return false
+	}
+	return true
+}
+