mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-17 21:12:39 +00:00
apprt/gtk: write StringList for boxed type of strings
This commit is contained in:
@@ -12,6 +12,8 @@ const gobject = @import("gobject");
|
||||
const gtk = @import("gtk");
|
||||
|
||||
pub const actions = @import("ext/actions.zig");
|
||||
const slice = @import("ext/slice.zig");
|
||||
pub const StringList = slice.StringList;
|
||||
|
||||
/// Wrapper around `gobject.boxedCopy` to copy a boxed type `T`.
|
||||
pub fn boxedCopy(comptime T: type, ptr: *const T) *T {
|
||||
@@ -64,4 +66,5 @@ pub fn gValueHolds(value_: ?*const gobject.Value, g_type: gobject.Type) bool {
|
||||
|
||||
test {
|
||||
_ = actions;
|
||||
_ = slice;
|
||||
}
|
||||
|
||||
106
src/apprt/gtk/ext/slice.zig
Normal file
106
src/apprt/gtk/ext/slice.zig
Normal file
@@ -0,0 +1,106 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const glib = @import("glib");
|
||||
const gobject = @import("gobject");
|
||||
|
||||
/// A boxed type that holds a list of string slices.
|
||||
pub const StringList = struct {
|
||||
arena: ArenaAllocator,
|
||||
strings: []const [:0]const u8,
|
||||
|
||||
pub fn create(
|
||||
alloc: Allocator,
|
||||
strings: []const [:0]const u8,
|
||||
) Allocator.Error!*StringList {
|
||||
var arena: ArenaAllocator = .init(alloc);
|
||||
errdefer arena.deinit();
|
||||
const arena_alloc = arena.allocator();
|
||||
var stored = try arena_alloc.alloc([:0]const u8, strings.len);
|
||||
for (strings, 0..) |s, i| stored[i] = try arena_alloc.dupeZ(u8, s);
|
||||
|
||||
const ptr = try alloc.create(StringList);
|
||||
errdefer alloc.destroy(ptr);
|
||||
ptr.* = .{ .arena = arena, .strings = stored };
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *StringList) void {
|
||||
self.arena.deinit();
|
||||
}
|
||||
|
||||
pub fn destroy(self: *StringList) void {
|
||||
const alloc = self.arena.child_allocator;
|
||||
self.deinit();
|
||||
alloc.destroy(self);
|
||||
}
|
||||
|
||||
pub const getGObjectType = gobject.ext.defineBoxed(
|
||||
StringList,
|
||||
.{
|
||||
.name = "GhosttyStringList",
|
||||
.funcs = .{
|
||||
.copy = &struct {
|
||||
fn copy(self: *StringList) callconv(.c) *StringList {
|
||||
return StringList.create(
|
||||
self.arena.child_allocator,
|
||||
self.strings,
|
||||
) catch @panic("OOM");
|
||||
}
|
||||
}.copy,
|
||||
.free = &struct {
|
||||
fn free(self: *StringList) callconv(.c) void {
|
||||
self.destroy();
|
||||
}
|
||||
}.free,
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
test "StringList create and destroy" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
const input: []const [:0]const u8 = &.{ "hello", "world" };
|
||||
const list = try StringList.create(alloc, input);
|
||||
defer list.destroy();
|
||||
|
||||
try testing.expectEqual(@as(usize, 2), list.strings.len);
|
||||
try testing.expectEqualStrings("hello", list.strings[0]);
|
||||
try testing.expectEqualStrings("world", list.strings[1]);
|
||||
}
|
||||
|
||||
test "StringList create empty list" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
const input: []const [:0]const u8 = &.{};
|
||||
const list = try StringList.create(alloc, input);
|
||||
defer list.destroy();
|
||||
|
||||
try testing.expectEqual(@as(usize, 0), list.strings.len);
|
||||
}
|
||||
|
||||
test "StringList boxedCopy and boxedFree" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
const input: []const [:0]const u8 = &.{ "foo", "bar", "baz" };
|
||||
const original = try StringList.create(alloc, input);
|
||||
defer original.destroy();
|
||||
|
||||
const copied: *StringList = @ptrCast(@alignCast(gobject.boxedCopy(
|
||||
StringList.getGObjectType(),
|
||||
original,
|
||||
)));
|
||||
defer gobject.boxedFree(StringList.getGObjectType(), copied);
|
||||
|
||||
try testing.expectEqual(@as(usize, 3), copied.strings.len);
|
||||
try testing.expectEqualStrings("foo", copied.strings[0]);
|
||||
try testing.expectEqualStrings("bar", copied.strings[1]);
|
||||
try testing.expectEqualStrings("baz", copied.strings[2]);
|
||||
|
||||
try testing.expect(original.strings.ptr != copied.strings.ptr);
|
||||
}
|
||||
Reference in New Issue
Block a user