-
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
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
<!--
Copyright 2025 Shota FUJI
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
-->
# core
Clients use this module and renders state struct managed by this.
Every function is blocking, so client is responsible for making them asynchronous.
## Code Styles
This section describes module internal rules for writing code.
### Struct creation function
A function that creates `struct Foo`,
- should be named `init`
- should return a value (`Foo`), rather than a pointer of `Foo` (`*Foo`)
- can return an error union
This is what many Zig projects, including `std`, uses.
Let the caller decide where to store.
```zig
const std = @import("std");
pub const Foo = struct {
bar: i32,
pub fn init() Foo {
return .{ bar = 0 };
}
}
```
### Struct creation and allocation function
A function that allocates and initializes `struct Foo`,
- should be named `make`
- should return a pointer (`*Foo`)
- should NOT take an allocator
- can return an error union
```zig
const std = @import("std");
pub const Foo = extern struct {
const allocator = std.heap.c_allocator;
bar: i32,
pub fn make() callconv(.C) std.mem.Allocator.Error!*Foo {
const dst = try allocator.create(Foo);
dst.* = .{
.bar = 0,
};
return dst;
}
}
comptime {
@export(&Foo.make, .{ .name = "plac_foo_make" });
}
```
### Exported struct internal
Exported structs' initial field must be a pointer to an internal struct:
```c
// plac.h
typedef struct {
void *__pri;
uint32_t bar;
} plac_foo;
```
```zig
// foo.zig
pub const Foo = extern struct {
internal: *Internal,
bar: u32,
const Internal = struct {
baz: u32,
};
};
```
Non-ABI stable fields (e.g. slices, reference counter) and internal fields should go inside `internal` field.
### Function parameters
Zig team has a plan to drop automatic pass-by-reference conversion for function parameters.
To minimize the cost of future migration, do not annotate a parameter with value type if pass-by-value is not desirable.
For this reason, struct methods should use pointer type for `self` parameter.
```zig
pub const Foo = struct {
// OK
pub fn bar(self: *Foo): void {}
// OK
pub fn bar(self: *const Foo): void {}
// NG
pub fn bar(self: Foo): void {}
}
```
### Exported functions
When an exported function takes a pointer, it should be an optional pointer rather than regular pointer, to guard against accidentally passing NULL pointer.
```zig
pub const Foo = extern struct {
pub fn bar(self: *const Foo) void {
// ...
}
}
export fn do_something(foo_ptr: ?*const Foo) void {
const foo = foo_ptr orelse return;
foo.bar();
}
```
If the function returns result code, define a code for receiving a NULL pointer.
If the function returns a pointer, return a NULL pointer and document about it in header file.