diff options
| author | 2025-04-29 13:48:34 -0400 | |
|---|---|---|
| committer | 2025-04-29 13:48:34 -0400 | |
| commit | 9ed545ae37dfd1db9758d724e5d10bae5cc00f04 (patch) | |
| tree | 2ac1c8b198c4114ad6edfcb67cd96224e53001c6 | |
| parent | README.md was updated to reflect last changes in API. (diff) | |
| download | zg-9ed545ae37dfd1db9758d724e5d10bae5cc00f04.tar.gz zg-9ed545ae37dfd1db9758d724e5d10bae5cc00f04.tar.xz zg-9ed545ae37dfd1db9758d724e5d10bae5cc00f04.zip | |
Add result.toOwned() to Normalize.zig
Closes #29
The README is also updated to reflect this change.
| -rw-r--r-- | README.md | 15 | ||||
| -rw-r--r-- | src/Normalize.zig | 9 |
2 files changed, 22 insertions, 2 deletions
| @@ -4,11 +4,11 @@ zg provides Unicode text processing for Zig projects. | |||
| 4 | 4 | ||
| 5 | ## Unicode Version | 5 | ## Unicode Version |
| 6 | 6 | ||
| 7 | The Unicode version supported by zg is 15.1.0. | 7 | The Unicode version supported by zg is `15.1.0`. |
| 8 | 8 | ||
| 9 | ## Zig Version | 9 | ## Zig Version |
| 10 | 10 | ||
| 11 | The minimum Zig version required is 0.14 dev. | 11 | The minimum Zig version required is `0.14`. |
| 12 | 12 | ||
| 13 | ## Integrating zg into your Zig Project | 13 | ## Integrating zg into your Zig Project |
| 14 | 14 | ||
| @@ -325,6 +325,17 @@ test "Normalization" { | |||
| 325 | try expect(try n.eql(allocator, "foϓ", "fo\u{03D2}\u{0301}")); | 325 | try expect(try n.eql(allocator, "foϓ", "fo\u{03D2}\u{0301}")); |
| 326 | } | 326 | } |
| 327 | ``` | 327 | ``` |
| 328 | The `Result` returned by normalization functions may or may not be copied from the | ||
| 329 | inputs given. For example, an all-ASCII input does not need to be a copy, and will | ||
| 330 | be a view of the original slice. Calling `result.deinit(allocator)` will only free | ||
| 331 | an allocated `Result`, not one which is a view. Thus it is safe to do | ||
| 332 | unconditionally. | ||
| 333 | |||
| 334 | This does mean that the validity of a `Result` can depend on the original string | ||
| 335 | staying in memory. To ensure that your `Result` is always a copy, you may call | ||
| 336 | `try result.toOwned(allocator)`, which will only make a copy if one was not | ||
| 337 | already made. | ||
| 338 | |||
| 328 | 339 | ||
| 329 | ## Caseless Matching via Case Folding | 340 | ## Caseless Matching via Case Folding |
| 330 | 341 | ||
diff --git a/src/Normalize.zig b/src/Normalize.zig index 7b87406..97c2649 100644 --- a/src/Normalize.zig +++ b/src/Normalize.zig | |||
| @@ -220,10 +220,19 @@ test "decompose" { | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | /// Returned from various functions in this namespace. Remember to call `deinit` to free any allocated memory. | 222 | /// Returned from various functions in this namespace. Remember to call `deinit` to free any allocated memory. |
| 223 | /// Note that normalization functions will not copy what they're given if no normalization is needed, if you | ||
| 224 | /// need to ensure that this Result outlasts the given string, call `try result.toOwned(allocator)`. This | ||
| 225 | /// will not make a third copy if the Result is already copied from the input. | ||
| 223 | pub const Result = struct { | 226 | pub const Result = struct { |
| 224 | allocated: bool = false, | 227 | allocated: bool = false, |
| 225 | slice: []const u8, | 228 | slice: []const u8, |
| 226 | 229 | ||
| 230 | /// Ensures that the slice result is a copy of the input, by making a copy if it was not. | ||
| 231 | pub fn toOwned(result: Result, allocator: mem.Allocator) error{OutOfMemory}!Result { | ||
| 232 | if (result.allocatod) return result; | ||
| 233 | return .{ .allocated = true, .slice = try allocator.dupe(u8, result.slice) }; | ||
| 234 | } | ||
| 235 | |||
| 227 | pub fn deinit(self: *const Result, allocator: mem.Allocator) void { | 236 | pub fn deinit(self: *const Result, allocator: mem.Allocator) void { |
| 228 | if (self.allocated) allocator.free(self.slice); | 237 | if (self.allocated) allocator.free(self.slice); |
| 229 | } | 238 | } |