aboutsummaryrefslogtreecommitdiff
path: root/core/fmt/example.odin
blob: a700b238e7da6e218d4d5cb0a6d10c04920a799f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#+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
}